leetcode 317 shortest distance from all buildings

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給出的結果纔有意義
                     }
                 }
             }
             
         }
         
    }
}
相關文章
相關標籤/搜索