算法-广度优先遍历-判断迷宫是否有出口

题目要求

题目的题目大致如下:判断在一个由 0(通路)和 1(墙壁)组成的二维迷宫中,是否存在一条从起点到终点的有效路径。我只能上下左右移动,不能穿墙,也不能走出迷宫。

一开始的思路

我的第一反应是使用递归。我构思了一个递归函数 bfs(x_now, y_now, ...),它会从当前位置开始,检查相邻的四个方向。如果某个方向是通畅的,我就继续向那个方向递归。如果最终能走到终点,那路径就找到了。

但很快我就发现这个思路不对。虽然我把函数命名为 bfs,但这种递归的实现方式本质上是深度优先搜索(DFS) 。它会沿着一条路走到死胡同才回头,这和迷宫问题中寻找路径的本质------向外"一层层扩散"------并不相符。而且,递归有一个潜在的风险:如果迷宫很大,或者存在很长的路径,递归的深度可能会导致栈溢出,程序会直接崩溃。我意识到,这种方法并不适合这个场景,于是我放弃了这条路线。

使用 deque 改进后的思路

BFS 的核心思想是"一层层"地探索,回顾之前数据结构的知识点后,我记起BFS一般都是用队列这个数据结构来实现的。为确保我能最快地找到所有相邻的、可达的位置。我选择了 collections.deque 来实现这个思路,因为它是一个双端队列,能高效地执行 append(入队)和 popleft(出队)操作,并且这两个操作时间复杂度都是O(1)。

我的具体步骤是:

  1. 创建一个 deque 队列,并将起点坐标 (x_1, y_1) 入队。
  2. 为了避免重复访问同一个位置,我选择直接修改迷宫矩阵,将访问过的通路 0 改为 1
  3. 然后,我进入一个 while 循环,只要队列不为空,就一直进行搜索。
  4. 在循环中,我从队列中取出一个位置 (x, y),然后检查它的上下左右四个邻居。
  5. 如果一个邻居满足三个条件:在迷宫范围内、是通路(值不为 1)、且从未被访问过,我就把这个邻居加入队列。

出现的问题

我按照上述思路实现了代码,但提交后,有一个测试点超时了。这让我很困惑,因为我自认为已经用了正确的 BFS 算法。

出现原因

经过仔细排查,我找到了问题所在:我标记已访问节点的位置不对。

python 复制代码
# 错误的代码逻辑
q.append((x_start, y_start))
while q:
    x, y = q.popleft()
    maze[x][y] = 1  # 错误!在这里标记
    # ...
    # 遍历邻居,将未标记的邻居入队
    if ... and maze[next_x][next_y] != 1:
        q.append((next_x, next_y))

我是在一个节点出队时 才将它标记为已访问。这意味着,在某个节点 (x, y) 还在队列中等待处理时,如果有其他路径也通向它,它就会被重复地加入队列。这导致队列中塞满了大量重复的坐标,程序做了很多无用功,效率大大降低,最终导致了超时。

解决方法

我意识到,我必须在节点入队时就立即将其标记为已访问。这样,每个可通行的节点只会被加入队列一次,大大减少了重复计算。

我将代码做了如下修改:

python 复制代码
# 正确的代码逻辑
q.append((x_start, y_start))
maze[x_start][y_start] = 1 # 改动:起点入队时就标记

while q:
    x, y = q.popleft()
    # ...
    for candidate in wait_list:
        next_x, next_y = candidate
        if in_maze(...) and maze[next_x][next_y] != 1:
            q.append(candidate)
            maze[next_x][next_y] = 1 # 改动:入队时立即标记

这次修改后,我的代码顺利通过了所有测试点。通过这个过程,我深刻理解了 BFS 中"何时标记已访问"这个细节的重要性,它直接决定了算法的效率。

相关推荐
橙小花34 分钟前
C语言:函数指针、二级指针、常量指针常量、野指针
c语言·数据结构·算法
西猫雷婶1 小时前
python学智能算法(三十一)|SVM-Slater条件理解
人工智能·python·算法·机器学习·支持向量机
仪器科学与传感技术博士1 小时前
python:以支持向量机(SVM)为例,通过调整正则化参数C和核函数类型来控制欠拟合和过拟合
开发语言·python·算法·机器学习·支持向量机·过拟合·欠拟合
一只乔哇噻1 小时前
Java,八股,cv,算法——双非研0四修之路day24
java·开发语言·经验分享·学习·算法
kokunka2 小时前
【数据结构】队列的顺序存储与链式存储(C语言版)
c语言·数据结构·算法
zhurui_xiaozhuzaizai3 小时前
多向量检索:lanchain,dashvector,milvus,vestorsearch,MUVERA
人工智能·算法·机器学习·全文检索·milvus
大阳1233 小时前
数据结构(概念及链表)
c语言·开发语言·数据结构·经验分享·笔记·算法·链表
2501_924731993 小时前
驾驶场景玩手机识别:陌讯行为特征融合算法误检率↓76% 实战解析
开发语言·人工智能·算法·目标检测·智能手机
爱编程的鱼4 小时前
计算机(电脑)是什么?零基础硬件软件详解
java·开发语言·算法·c#·电脑·集合