1 0 2 0 1 0 0 0 0 0 0 0 1 0 0
第一个building, 把涂色把0变成-1, 同一层最终会涂成相同颜色-1node
1 -1 2 -1 1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1
距离矩阵ui
0 1 0 5 0 1 2 3 4 5 2 3 0 5 6
第一个building, 把涂色把-1变成-2, 同一层最终会涂成相同颜色-2code
1 -2 2 -2 1 -2 -2 -2 -2 -2 -2 -2 1 -2 -2
距离矩阵it
0 6 0 6 0 6 6 6 6 6 8 8 0 8 8
第一个building, 把涂色把-2变成-3, 同一层最终会涂成相同颜色-3io
1 -3 2 -3 1 -3 -3 -3 -3 -3 -3 -3 1 -3 -3
距离矩阵class
0 9 0 9 0 9 8 7 8 9 10 9 0 9 10
为了避路径重复,咱们有两种方法,一种是用额外的空间visited, 一种是改变输入。
从第一个点出发0表示空地,-1表示已经走过的空地,避免重复。
从第二个点出发-1表示空地,-2表示已经走过的空地,避免重复。
看起来就像一层层的涂色。test
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给出的结果才有意义 } } } } } }