模板
实现:利用queue存储中间结果
int BFS(Node start, Node target) {
queue<Node> q;
unordered_set<Node> visited;
q.push(start);
visited.insert(start);
while (!q.empty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
Node cur = q.front();
q.pop();
if (cur == target)
return step;
for (Node x : cur.adj()) {
if (visited.count(x) == 0) {
q.push(x);
visited.insert(x);
}
}
}
}
// 如果走到这里,说明在图中没有找到目标节点
}
示例
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
输入:
0 0 0
0 1 0
1 1 1
输出:
0 0 0
0 1 0
1 2 1
广度优先遍历实现原理:
假设对于1个位置为0,则有如下
_ _ _ _ _ 1 _ _ 2 1 2 _ 2 1 2 3 2 1 2 3
_ 0 _ _ ==> 1 0 1 _ ==> 1 0 1 2 ==> 1 0 1 2 ==> 1 0 1 2
_ _ _ _ _ 1 _ _ 2 1 2 _ 2 1 2 3 2 1 2 3
_ _ _ _ _ _ _ _ _ 2 _ _ 3 2 3 _ 3 2 3 4
假设有2个位置为0,则有如下
_ 1 _ _ 2 1 2 _ 2 1 2 3
1 0 1 _ ==> 1 0 1 2 ==> 1 0 1 2
_ 1 0 1 2 1 0 1 2 1 0 1
_ _ 1 _ _ 2 1 2 3 2 1 2
具体实现:
dirs:用于上下左右搜索
flag:用于确认当前位置是否已经被处理
dis:用于输出结果
先把为0的所有位置加入队列,取出队列中的每个元素(每个元素表示实际的位置处),
上下左右搜索不在队列中的其他位置,将搜索到的新的位置加入队列中,并把该位置用于
结果输出的(dis)数值+1;将用于搜索的元素从队列中删除,。。。持续搜索队列
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
queue<pair<int, int>> que;
vector<vector<int>> dis(m, vector<int> (n)); // 存储距离结果
vector<vector<int>> flag(m, vector<int> (n)); // 用于确认当前点是否已经被处理
int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// 初始化队列,将位置为 0 的加入队列中
for (int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
que.push({i, j});
flag[i][j] = 1; // 表示当前位置已经被处理
}
}
}
// 广度优先搜索
while (!que.empty()) {
auto [o_i, o_j] = que.front();
que.pop();
for (int i = 0; i < 4; i++) {
int new_i = o_i + dirs[i][0];
int new_j = o_j + dirs[i][1];
if (new_i >= 0 && new_i < m && new_j >= 0 && new_j < n && flag[new_i][new_j] != 1) {
dis[new_i][new_j] += dis[o_i][o_j] + 1;
que.push({new_i, new_j});
flag[new_i][new_j] = 1;
}
}
}
return dis;
}
};