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

LeetCode封闭岛屿问题:BFS超时DFS正常的原因解析

封闭岛屿数量问题:BFS超时但DFS正常的原因分析

在解决LeetCode「Number of Closed Islands」问题时,出现了BFS解法超时但DFS解法正常运行的情况,此前仅得知“队列带来额外开销”的说法,现具体分析原因:

核心问题:你提供的BFS代码与当前问题不匹配

你贴出的BFS代码是另一道题「连通网络的操作次数(makeConnected)」的实现,完全没有针对「封闭岛屿数量」问题的逻辑(比如未处理二维网格、未排除边界岛屿等),这是导致超时或运行错误的直接原因。

假设使用正确的BFS代码,仍可能超时的具体原因

如果是针对该问题的正确BFS实现,超时可能来自以下几点:

1. 队列的缓存局部性劣势

DFS使用的递归栈是线程栈的连续内存区域,缓存命中率更高;而BFS的队列(如std::queue)通常基于堆内存分配,节点地址分散,缓存访问效率较低,在大规模网格下会累积性能差距。

2. 未及时标记访问状态导致重复入队

如果BFS中弹出节点时才标记已访问(而非入队时就标记),会导致同一个节点被多个邻居重复入队。例如节点A的两个邻居B、C,当处理A时,B未被标记,会被入队;后续处理其他节点时,C也会把未标记的B再次入队,造成队列中存在大量重复元素,额外增加处理开销。而DFS在进入节点时就标记为已访问,从根源避免了重复处理。

3. 数据结构的额外开销

如果BFS实现中使用了unordered_map这类哈希结构存储邻接关系,哈希查找、链表遍历的开销远高于DFS直接操作二维数组的索引访问,这也是性能差距的来源之一。

针对该问题的正确BFS示例

class Solution {
public:
    int closedIsland(vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        int count = 0;
        // 先淹没边界的岛屿
        for (int i = 0; i < m; ++i) {
            if (grid[i][0] == 0) bfs(grid, i, 0);
            if (grid[i][n-1] == 0) bfs(grid, i, n-1);
        }
        for (int j = 0; j < n; ++j) {
            if (grid[0][j] == 0) bfs(grid, 0, j);
            if (grid[m-1][j] == 0) bfs(grid, m-1, j);
        }
        // 统计封闭岛屿
        for (int i = 1; i < m-1; ++i) {
            for (int j = 1; j < n-1; ++j) {
                if (grid[i][j] == 0) {
                    bfs(grid, i, j);
                    count++;
                }
            }
        }
        return count;
    }

private:
    void bfs(vector<vector<int>>& grid, int row, int col) {
        int m = grid.size();
        int n = grid[0].size();
        queue<pair<int, int>> q;
        q.push({row, col});
        grid[row][col] = 1; // 入队时立即标记已访问
        // 四个方向
        vector<pair<int, int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};
        while (!q.empty()) {
            auto curr = q.front();
            q.pop();
            for (auto& dir : dirs) {
                int r = curr.first + dir.first;
                int c = curr.second + dir.second;
                if (r >= 0 && r < m && c >=0 && c < n && grid[r][c] == 0) {
                    grid[r][c] = 1; // 入队前标记,避免重复入队
                    q.push({r, c});
                }
            }
        }
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:02:09