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

题目要求

题目的题目大致如下:判断在一个由 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 中"何时标记已访问"这个细节的重要性,它直接决定了算法的效率。

相关推荐
2501_924878591 小时前
强光干扰下漏检率↓78%!陌讯动态决策算法在智慧交通违停检测的实战优化
大数据·深度学习·算法·目标检测·视觉检测
耳总是一颗苹果2 小时前
排序---插入排序
数据结构·算法·排序算法
YLCHUP2 小时前
【联通分量】题解:P13823 「Diligent-OI R2 C」所谓伊人_连通分量_最短路_01bfs_图论_C++算法竞赛
c语言·数据结构·c++·算法·图论·广度优先·图搜索算法
花火|3 小时前
算法训练营day62 图论⑪ Floyd 算法精讲、A star算法、最短路算法总结篇
算法·图论
GuGu20243 小时前
新手刷题对内存结构与形象理解的冲突困惑
算法
汤永红3 小时前
week4-[二维数组]平面上的点
c++·算法·平面·信睡奥赛
晴空闲雲3 小时前
数据结构与算法-字符串、数组和广义表(String Array List)
数据结构·算法
颜如玉5 小时前
位运算技巧总结
后端·算法·性能优化
冷月半明5 小时前
时间序列篇:Prophet负责优雅,LightGBM负责杀疯
python·算法
秋难降6 小时前
聊聊 “摸鱼式” 遍历 —— 受控遍历的小心机
数据结构·算法·程序员