• 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 ++;
            }
        }
    }
    
  • 相关阅读:
    echarts动态设置主体颜色
    spring security session
    Spark RDD函数:
    MapReduce TOP n
    feign 使用示例
    trie树
    动态修改注解(annotation)值
    golang插件
    Kafka Streams Example
    tcp并发(c18w)
  • 原文地址:https://www.cnblogs.com/reboot329/p/6284581.html
Copyright © 2020-2023  润新知