给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
输入:mat = [[0,0,0],[0,1,0],[0,0,0]] 输出:[[0,0,0],[0,1,0],[0,0,0]]
输入:mat = [[0,0,0],[0,1,0],[1,1,1]] 输出:[[0,0,0],[0,1,0],[1,2,1]]
首先把每个源点 0 入队,然后从各个 0 同时开始一圈一圈的向 1 扩散(每个 1 都是被离它最近的 0 扩散到的 ),扩散的时候可以设置 int[][] dist 来记录距离(即扩散的层次)并同时标志是否访问过。对于本题是可以直接修改原数组 int[][] matrix 来记录距离和标志是否访问的,这里要注意先把 matrix 数组中 1 的位置设置成 -1 (设成Integer.MAX_VALUE,m * n,10000都行,只要是个无效的距离值来标志这个位置的 1 没有被访问过就行)
class Solution {
public int[][] updateMatrix(int[][] matrix) {
// 首先将所有的 0 都入队,并且将 1 的位置设置成 -1,表示该位置是 未被访问过的 1
Queue<int[]> queue = new LinkedList<>();
int m = matrix.length, n = matrix[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
queue.offer(new int[] {i, j});
} else {
matrix[i][j] = -1;
}
}
}
int[] dx = new int[] {-1, 1, 0, 0};
int[] dy = new int[] {0, 0, -1, 1};
while (!queue.isEmpty()) {
int[] point = queue.poll();
int x = point[0], y = point[1];
for (int i = 0; i < 4; i++) {
int newX = x + dx[i];
int newY = y + dy[i];
// 如果四邻域的点是 -1,表示这个点是未被访问过的 1
// 所以这个点到 0 的距离就可以更新成 matrix[x][y] + 1。
if (newX >= 0 && newX < m && newY >= 0 && newY < n
&& matrix[newX][newY] == -1) {
matrix[newX][newY] = matrix[x][y] + 1;
queue.offer(new int[] {newX, newY});
}
}
}
return matrix;
}
}