问题描述
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
输入:
0 0 0
0 1 0
0 0 0
输出:
0 0 0
0 1 0
0 0 0
输入:
0 0 0
0 1 0
1 1 1
输出:
0 0 0
0 1 0
1 2 1
注意:
- 给定矩阵的元素个数不超过 10000。
- 给定矩阵中至少有一个元素是 0。
- 矩阵中的元素只在四个方向上相邻: 上、下、左、右。
思路
BFS,一圈一圈的向外扩散。(方法一)
多源BFS:向外扩散。首先把每个源点 0 入队,然后从各个 0 同时开始一圈一圈的向 1 扩散(每个 1 都是被离它最近的 0 扩散到的 ),扩散的时候可以设置 int[][] dist
来记录距离(即扩散的层次)并同时标志是否访问过。对于本题是可以直接修改原数组 int[][] matrix
来记录距离和标志是否访问的,这里要注意先把 matrix
数组中 1
的位置设置成 -1
(设成Integer.MAX_VALUE
啦,m * n
啦,10000
啦都行,只要是个无效的距离值来标志这个位置的 1
没有被访问过就行辣~)
方法一
class Solution {
int[] direcX = new int[]{-1,0,1,0};
int[] direcY = new int[]{0,-1,0,1};
public int[][] updateMatrix(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0) return null;
int[][] res = new int[matrix.length][matrix[0].length];
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
if(matrix[i][j] == 0) continue;
res[i][j] = BFS(matrix,res,i,j);
}
}
return res;
}
private int BFS(int[][] matrix,int[][] res, int i,int j){
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{i,j});
while(!queue.isEmpty()){
int[] tmp = queue.poll();
if(matrix[tmp[0]][tmp[1]] == 0){
return Math.abs(tmp[0]-i) + Math.abs(tmp[1]-j);
}
for(int step = 0; step < 4; step++){
int curX = tmp[0]+direcX[step];
int curY = tmp[1]+direcY[step];
if(curX<0||curX>matrix.length-1||curY<0||curY>matrix[0].length-1){
continue;
}
queue.add(new int[]{curX,curY});
}
}
return 0;
}
}
方法二
class Solution {
int[] direcX = new int[]{-1,0,1,0};
int[] direcY = new int[]{0,-1,0,1};
public int[][] updateMatrix(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0) return null;
Queue<int[]> queue = new LinkedList<>();
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
if(matrix[i][j] == 0){
queue.add(new int[]{i,j});
}else{
matrix[i][j] = -1;
}
}
}
while(!queue.isEmpty()){
int[] tmp = queue.poll();
int x = tmp[0],y = tmp[1];
for(int i = 0; i < 4; i++){
int curX = x+direcX[i], curY = y+direcY[i];
if(curX<0||curX>=matrix.length||curY<0||curY>=matrix[0].length||matrix[curX][curY]>-1){
continue;
}
matrix[curX][curY] = matrix[x][y]+1;
queue.add(new int[]{curX,curY});
}
}
return matrix;
}
}