面试算法:图的 BFS 与 DFS

图题通常先确定建图方式。

邻接表

std::vector<std::vector<int>> graph(n);
graph[u].push_back(v);

DFS

DFS 适合连通块、路径搜索、拓扑相关问题。

void dfs(int u) {
    visited[u] = true;
    for (int v : graph[u]) {
        if (!visited[v]) dfs(v);
    }
}

BFS

BFS 适合无权图最短步数。

访问标记必须及时设置,否则会重复入队。

建图比搜索更容易错

图题常常不是 DFS/BFS 写错,而是边建错。无向图要双向加边,有向图只加一个方向;网格图要检查边界;带权图需要保存权重。

DFS 适合“走到底”

DFS 适合枚举路径、判断连通块、做拓扑搜索。写递归 DFS 时,要注意递归深度。如果节点很多,可能需要改成显式栈。

BFS 适合“按层扩散”

迷宫最短路可以这样看:

queue.push(start);
dist[start] = 0;
while (!queue.empty()) {
    auto u = queue.front();
    queue.pop();
    for (auto v : next(u)) {
        if (!visited[v]) {
            visited[v] = true;
            dist[v] = dist[u] + 1;
            queue.push(v);
        }
    }
}

面试时怎么讲

先说明状态是什么,再说明邻居如何生成,最后说明 visited 在什么时候设置。这个顺序能减少很多重复访问和死循环问题。

评论

...

正在读取评论。