一、概述
BFS问题的本质就是让你在一幅图中找到从起点 start
到终点 target
的最近距离,即用来解决最短路径问题。第一次遍历到目的节点时,所经过的路径是最短路径。
几个要点:
- 只能用来求解无权图的最短路径问题
- 队列:用来存储每一层遍历得到的节点
- 标记:对于遍历过的结点,应将其标记,以防重复访问
二、框架
// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
Queue<Node> q; // 核心数据结构
Set<Node> visited; // 避免走回头路
q.offer(start); // 将起点加入队列
visited.add(start);
int step = 0; // 记录扩散的步数
while (q not empty) {
int sz = q.size();
/* 将当前队列中的所有节点向四周扩散 */
for (int i = 0; i < sz; i++) {
Node cur = q.poll();
/* 划重点:这里判断是否到达终点 */
if (cur is target)
return step;
/* 将 cur 的相邻节点加入队列 */
for (Node x : cur.adj()) {
if (x not in visited) {
q.offer(x);
visited.add(x);
}
}
}
/* 划重点:更新步数在这里 */
step++;
}
}
BFS 的核心数据结构是队列q
;cur.adj()
泛指 cur
相邻的节点,比如说二维数组中,cur
上下左右四面的位置就是相邻节点;visited
的主要作用是防止走回头路,大部分时候都是必须的,但是像一般的二叉树结构,没有子节点到父节点的指针,不会走回头路就不需要 visited
。
三、leetcode例题
leetcode-111-二叉树最小深度
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int minDepth(TreeNode* root) {
if (!root) return 0;
queue<TreeNode*> que;
que.push(root);
// root 本身就是一层,depth 初始化为 1
int depth = 1;
while (!que.empty()) {
int num = que.size();
/* 将当前队列中的所有节点向四周扩散 */
for (int i = 0; i < num; ++i) {
TreeNode* cur = que.front();
que.pop();
/* 判断是否到达终点 */
if (cur->left == nullptr && cur->right == nullptr) {
return depth;
}
/* 将 cur 的相邻节点加入队列 */
if (cur->left != nullptr) {
que.push(cur->left);
}
if (cur->right != nullptr) {
que.push(cur->right);
}
}
/* 这里增加步数 */
depth++;
}
return depth;
}
};
参考: