分析
一个只有0和1的矩阵,让我们求每一个1到离其最近的0的距离,其实也就是求一个距离场,而求距离场那么BFS将是不二之选。与题目1162.地图分析类似,都是多源BFS。树的BFS是单源的,图的BFS是多源的。
能从一个点出发求最短距离就是BFS,借用大佬的图片
BFS解题模板
BFS使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当作当前遍历点:
- 如果不知道确定当前遍历到哪一层:
while queue not NULL
cur = queue.front();
queue.pop();
for 节点 in cur的所有相邻节点:
if 该节点有效且没有访问过
queue.push(该节点);
- 如果知道遍历到哪一层
这里增加了level表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
int level = 0;
while queue not NULL
size = queue.size();
while (size--) {
cur = queue.front();
queue.pop();
for 节点 in cur的所有相邻节点
queue.push(该节点);
}
level++;
代码
class Solution {
public:
// 声明四个方向
vector<vector<int>>dir={{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
// 存储结果
vector<vector<int>> res(m, vector<int>(n));
// 存储该点是否访问过
vector<vector<int>> vis(m, vector<int>(n));
// (i,j)组成个pair
queue<pair<int, int>> que;
// 所有为0的节点入队,且置访问位为1
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == 0) {
que.push(make_pair(i, j));
vis[i][j] = 1;
}
}
}
// BFS
while (!que.empty()) {
//获取队头元素
pair<int, int> qt = que.front();
//出队
que.pop();
// 队列中的每个节点,遍历其点的四个方向
for (int i = 0; i < 4; ++i) {
int newx = qt.first + dir[i][0];
int newy = qt.second + dir[i][1];
// 四个方向未被访问过的话,更新距[newx][newy] + 1
if (newx >= 0 && newy >= 0 && newx < m && newy < n && !vis[newx][newy]) {
res[newx][newy] = res[qt.first][qt.second] + 1;
que.push(make_pair(newx, newy));
vis[newx][newy] = 1;
}
}
}
return res;
}
};