1 0 2 0 1
0 0 0 0 0
0 0 1 0 0
第一个building, 把涂色把0变成-1, 同一层最终会涂成相同颜色-1
1 -1 2 -1 1
-1 -1 -1 -1 -1
-1 -1 1 -1 -1
距离矩阵
0 1 0 5 0
1 2 3 4 5
2 3 0 5 6
第一个building, 把涂色把-1变成-2, 同一层最终会涂成相同颜色-2
1 -2 2 -2 1
-2 -2 -2 -2 -2
-2 -2 1 -2 -2
距离矩阵
0 6 0 6 0
6 6 6 6 6
8 8 0 8 8
第一个building, 把涂色把-2变成-3, 同一层最终会涂成相同颜色-3
1 -3 2 -3 1
-3 -3 -3 -3 -3
-3 -3 1 -3 -3
距离矩阵
0 9 0 9 0
9 8 7 8 9
10 9 0 9 10
为了避路径重复,我们有两种方法,一种是用额外的空间visited, 一种是改变输入。
从第一个点出发0表示空地,-1表示已经走过的空地,避免重复。
从第二个点出发-1表示空地,-2表示已经走过的空地,避免重复。
看起来就像一层层的涂色。
public class Solution {
private int[] dx = {0, 1, 0, -1}, dy = {1, 0, -1, 0};
private int min = Integer.MAX_VALUE;
public int shortestDistance(int[][] grid) {
if(grid == null || grid.length == 0) return 0;
int m = grid.length, n = grid[0].length;
int[][] distance = new int[m][n]; // 记录累加距离
int start = 0;
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
if(grid[i][j] == 1) //入口
bfs(grid, distance, i, j, start--); //每次涂色之后,换另一种颜色
}
}
return min == Integer.MAX_VALUE ? -1 : min;
}
public void bfs(int[][] grid, int[][] distance, int i, int j, int start){
ArrayDeque<int[]> q = new ArrayDeque<>();
q.offer(new int[]{i,j});
int level = 0, m = grid.length, n = grid[0].length;
min = Integer.MAX_VALUE;
while(!q.isEmpty()){
int size = q.size(); // 涂色的时候,记录当前层的大小
level++; // 进入下一层,需要增加距离
for(int k=0; k<size; k++){
int[] node = q.poll();
for(int pos=0; pos<4; pos++){
int x = node[0] + dx[pos];
int y = node[1] + dy[pos]; // 只会走空地,!=1, !=2的地方
if(x>=0 && y>=0 && x<m && y<n && grid[x][y] == start){
q.offer(new int[]{x, y});
grid[x][y] = start-1; // 涂色,可以用vistied[][]代替
distance[x][y] += level; // 累加距离
min = Math.min(min, distance[x][y]); //记录最值,实际上最后一个building给出的结果才有意义
}
}
}
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。