题目链接:
题目描述:
解法
先看懂题目
解法一:一个位置一个位置求(最差的情况下会非常恐怖)
解法二:多源BFS+正难则反
把1当成起点就很难,因为不好更新。
所以把0当作起点,1当作终点,从0开始向外扩展,遇到1就把最短路数填进去。
- 把所有的0位置加入到队列中
- 一层一层的向外扩展即可
其他注意:
需要一个
bool
数组来标记当前位置是否搜索过。层序遍历的循环里面要求一个
[step,sz]
的,和一个dist[][]
数组记录最终结果,这题我们可以把bool
数组,[step,sz]
都放进dist[][]
数组
- 把dist的值都初始化为-1,来标记没有搜索过,代替
bool
数组- 值和层数都可以填入
dist[][]
数组
C++ 算法代码:
class Solution {
// 四个方向的移动:右、左、下、上
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
int m = mat.size(), n = mat[0].size();
// 初始化距离矩阵
// dist[i][j] == -1 表示该位置还未被访问
// dist[i][j] != -1 表示该位置到最近0的距离
vector<vector<int>> dist(m, vector<int>(n, -1));
queue<pair<int, int>> q;
// 1. 多源BFS初始化:将所有0的位置作为起点
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (mat[i][j] == 0) {
q.push({i, j});
dist[i][j] = 0; // 0到自己的距离是0
}
// 2. 开始BFS遍历
while (q.size()) {
auto [a, b] = q.front();
q.pop();
// 遍历四个方向
for (int i = 0; i < 4; i++) {
int x = a + dx[i], y = b + dy[i];
// 检查新位置是否在矩阵范围内且未被访问过
if (x >= 0 && x < m && y >= 0 && y < n && dist[x][y] == -1) {
// 更新距离:当前点的距离 = 前一个点的距离 + 1
dist[x][y] = dist[a][b] + 1;
// 将新位置加入队列,继续BFS
q.push({x, y});
}
}
}
return dist; // 返回距离矩阵
}
};