题目地址:
https://leetcode.com/problems/01-matrix/
给定一个二维 m m m行 n n n列的 0 − 1 0-1 0−1矩阵 A A A,返回一个矩阵 B B B,使得 B [ i ] [ j ] B[i][j] B[i][j]等于 A [ i ] [ j ] A[i][j] A[i][j]与与其最近的 0 0 0的曼哈顿距离。题目保证矩阵里至少有一个 0 0 0。
动态规划方法可以参考https://blog.csdn.net/qq_46105170/article/details/109233926。下面介绍一个BFS的方法。
思路是BFS。先将所有的 0 0 0入队,然后一层一层向外更新,每走一步就将下一个 A A A中等于 1 1 1的点的步数更新。并且,只需要将被更新过的顶点加入队列即可,“被更新”的意思是,如果发现某个顶点与最近 0 0 0的距离被更新了,那么它就可以加入队列然后以此去更新别的 A A A中的 1 1 1,否则就不用加入队列了,因为如果未更新而入队,以此更新别的点只会得到更差的结果。代码如下:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
public int[][] updateMatrix(int[][] matrix) {
int n = matrix.length, m = matrix[0].length;
int[][] res = new int[n][m];
// 将答案初始化为-1
for (int[] row : res) {
Arrays.fill(row, -1);
}
// 将所有0位置的答案标记为0,并将其位置入队
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0) {
res[i][j] = 0;
queue.offer(new int[]{i, j});
}
}
}
int[] dir = {1, 0, -1, 0, 1};
while (!queue.isEmpty()) {
int[] cur = queue.poll();
int x = cur[0], y = cur[1];
for (int j = 0; j < 4; j++) {
int nextX = x + dir[j], nextY = y + dir[j + 1];
if (0 <= nextX && nextX < n && 0 <= nextY && nextY < m && res[nextX][nextY] == -1) {
res[nextX][nextY] = res[x][y] + 1;
queue.offer(new int[]{nextX, nextY});
}
}
}
return res;
}
}
时间复杂度和具体矩阵是什么样的有关,可以认为是 O ( m n ) O(mn) O(mn),空间复杂度 O ( m n ) O(mn) O(mn)。