317. Shortest Distance from All Buildings


2019-July-08

和296的区别就是,有了障碍的存在,导致没法简单地纵向横向算距离= =
然后从每个点开始BFS,难点在于:
为了不走回头路,从一个点开始BFS的时候得标记走过的格子,需要一个新的boolean[m][n]的来标记,然后这个点走完需要reset
需要另一个int[m][n]来存每个点到各个HOUSE的距离,BFS的过程中更新。或许可以在原有的GRID上标记,比如用负数-1 -2代表距离,这样不至于和1 2搞混。
-1的情况怎么办?比如我有1 0 2 0 1这样被2隔开。这样每个点BFS完,不能简单的重新reset boolean[m][n]因为要遍历看看是不是所有点都VISIT了。
然后爆炸了。。
我看一刷的做法是用了个特别的flag
这个FLAG在BFS的时候代表我们正在给第几个HOURS进行BFS,然后用了负数便于区分1和2.
在原有的GRID上更新,在第一个点BFS后所有的0变成-1,代表被1个hourse BFS过了。
然后第二个点进行BFS的时候,找空地要看是不是 == -1 而不是0,。
第三个点就是 == -2
这样。。同时更新distanceGrid,这个用来存距离,遍历之后distanceGrid[i][j]代表IJ到所有点的距离

算总数的时候,比如总共8个点,只计算grid[i][j] == -8的点,-7, -6, -5 。。。说明有的房子没有BFS到,就是1 0 2 0 1这种情况,2个0都不是有效解

class Solution {
    
    private static final int[] DIRECTIONS = new int[] {0, 1, 0, -1, 0};
    
    public int shortestDistance(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) return -1;
        
        int[][] distanceGrid = new int[grid.length][grid[0].length];
        int noXhourse = 0; // negative of No.n hourse
        
        for (int i = 0; i < grid.length; i ++) {
            for (int j = 0; j < grid[0].length; j ++) {
                if (grid[i][j] == 1) {
                    bfs(i, j, distanceGrid, grid, noXhourse);
                    noXhourse --;
                }
            }
        }
        
        int res = Integer.MAX_VALUE;
        
        for (int i = 0; i < grid.length; i ++) {
            for (int j = 0; j < grid[0].length; j ++) {
                // visited by X hourses
                if (grid[i][j] == noXhourse) {
                    res = Math.min(res, distanceGrid[i][j]);
                }
            }
        }
        
        return res == Integer.MAX_VALUE ? -1 : res;
        
    }
    
    public void bfs(int i, int j, int[][] distanceGrid, int[][] grid, int noXhourse) {
        ArrayDeque<int[]> q = new ArrayDeque<>();
        q.offerLast(new int[] {i, j});
        int distanceToIJ = 1;
        
        while (!q.isEmpty()) {
            int tempSize = q.size();
            for (int k = 0; k < tempSize; k ++) {
                int[] tempLocation = q.pollFirst();
                int x = tempLocation[0];
                int y = tempLocation[1];
                for (int d = 0; d < 4; d ++) {
                    int nextX = x + DIRECTIONS[d];
                    int nextY = y + DIRECTIONS[d + 1];
                    
                    if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) continue;
                    
                    if (grid[nextX][nextY] == noXhourse) {
                        distanceGrid[nextX][nextY] += distanceToIJ;
                        grid[nextX][nextY] = noXhourse - 1;
                        q.offerLast(new int[] {nextX, nextY});
                    }
                }
            }
            distanceToIJ ++;
        }
    }
}
posted @ 2017-01-14 03:44  哇呀呀..生气啦~  阅读(440)  评论(0)    收藏  举报