You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BFS是否仅能搜索最短路径?结合LeetCode题探讨

问题背景

对应题目为二进制矩阵中的最短路径,题目规则如下:

  • 给定元素为0/1的n×n二进制矩阵grid,返回从左上角单元格(0,0)到右下角单元格(n-1,n-1)的最短路径
  • 路径需满足两个要求:① 路径访问的所有单元格值均为0;② 路径中所有相邻单元格为8方向连通(即单元格互不重复,且共享边或夹角)

该问题的常规解法是基于队列实现BFS,参考代码如下:

int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
    if (grid[0][0] == 1) return -1;
    int res = 0, n = grid.size(), m = grid[0].size();
    vector<vector<int>> visited(n, vector<int>(m, 0));
    visited[0][0] = 1;
    queue<vector<int>> q;
    q.push({ 0, 0 });
    vector<vector<int>> dirs{ {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} };
    while (!q.empty()) {
        ++res;
        for (int i = q.size(); i > 0; --i) {
            auto t = q.front(); q.pop();
            if (t[0] == n - 1 && t[1] == n - 1) return res;
            for (auto dir : dirs) {
                int x = t[0] + dir[0], y = t[1] + dir[1];
                if (x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == 1 || visited[x][y]) continue;
                visited[x][y] = 1; 
                q.push({ x, y });
            }
        }
    }
    return -1;
}
疑问解答

BFS并非仅能求解最短路径问题。
大家通常把BFS和无权图最短路径绑定,本质是因为最短路径场景下用了「全局访问标记+层序遍历」的优化:第一次遍历到某个节点时,对应的路径长度一定是所有可达路径里最短的,因此标记节点已访问、避免后续重复入队,碰到终点时可以直接返回结果,时间复杂度能控制在O(nm)级别,效率很高。但全局访问标记是针对最短路径场景的优化手段,不是BFS算法本身的强制约束。

如果目标是查找所有可达路径,BFS完全可以胜任,你写的fun2就是可行的实现:

vector<vector<vector<int>>> fun2(vector<vector<int>> grid, int x, int y)
{
    vector<vector<vector<int>>> res;
    if (grid[x][y] == 1) return res;
    int n = grid.size(), m = grid[0].size();
    queue<vector<vector<int>>> q;
    q.push({ { x, y } });
    vector<vector<int>> dirs{ {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} };
    while (!q.empty()) {
        for (int i = q.size(); i > 0; --i) {
            auto t = q.front(); q.pop();
            unordered_set<string> st;
            for (auto &it : t) st.insert(to_string(it[0]) + ',' + to_string(it[1]));
            int xx = t.back()[0], yy = t.back()[1];
            if (grid[xx][yy] == 2) res.push_back(t);
            for (auto dir : dirs) {
                int x = xx + dir[0], y = yy + dir[1];
                if (x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == 1 || st.count(to_string(x) + ',' + to_string(y))) continue;
                auto tem = t;
                tem.push_back({ x, y });
                q.push(tem);
            }
        }
    }
    return res;
}

这个实现放弃了全局visited数组,转而给队列中存储的每一条独立路径单独维护已访问节点集合(代码中用unordered_set存储当前路径的所有坐标,避免单条路径内出现重复节点),每次扩展路径时只要新节点满足边界、值的要求,且不在当前路径的已访问集合中,就生成新的完整路径入队,队列为空时就能拿到所有符合要求的可达路径。

两种BFS实现的核心差异只是适用场景不同:

  • 求最短路径的BFS:靠全局标记剪枝,每个节点仅入队一次,效率高,但无法记录所有路径
  • 求所有路径的BFS:不做全局剪枝,节点会在不同路径中重复入队,时间、空间复杂度随矩阵规模指数级上升,和递归DFS枚举所有路径的复杂度一致,仅遍历顺序为按路径长度层序推进而已。

注意你写的fun2中判断终点的条件是grid[xx][yy] == 2,属于自定义终点标记,如果要适配原题的右下角终点需求,把判断条件改为xx == n-1 && yy == m-1即可,整体逻辑没有问题。

内容的提问来源于stack exchange,提问作者user6703592

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:06:22