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給出的結果纔有意義 } } } } } }