zoukankan      html  css  js  c++  java
  • Leetcode: Shortest Distance from All Buildings

    You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2, where:
    
    Each 0 marks an empty land which you can pass by freely.
    Each 1 marks a building which you cannot pass through.
    Each 2 marks an obstacle which you cannot pass through.
    For example, given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2):
    
    1 - 0 - 2 - 0 - 1
    |   |   |   |   |
    0 - 0 - 0 - 0 - 0
    |   |   |   |   |
    0 - 0 - 1 - 0 - 0
    The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7.
    
    Note:
    There will be at least one building. If it is not possible to build such house according to the above rules, return -1.

    Adopted approach: start from each building, try to reach all 0.  Alternertive approch can be start from each 0, try to reach all buildings. Which is way is better depends on number of empty spaces vs buildings

    Here is start from each building

    Start from each building, do bfs to calculate the shortest distance to each empty land which it can reach.

    Repeat this process for all buildings. we can get the sum of shortest distance from every '0' to all reachable buildings. This value is stored in 'distance[][]'. 

    Notice that there are empty lands that can not be reached from some buildings. like (0, 2) below, it can not be reached from the building (0, 0) and (2, 2)

    1 1 0

    0 0 1

    0 0 1

    Therefore, we also count how many building each '0' can be reached. It is stored in reach[][]. This can be done during the BFS. We also need to count how many total buildings are there in the matrix, which is stored in 'buildingNum'.

    Our building should be placed at those empty places which can reach all buildings, that is to say, reach[i][j] == buildingNum

    we choose the shortest distances among all these empty places.

    Be careful the case where there are only buildings and no empty lands, like [[1]]. so shortest distance at last is still Integer.MAX_VALUE should be turned to -1

    Syntax: use direction matrix can save lines of codes

     1 public class Solution {
     2     public int shortestDistance(int[][] grid) {
     3         if (grid==null || grid.length==0 || grid[0].length==0) return -1;
     4         int m = grid.length;
     5         int n = grid[0].length;
     6         int[][] dist = new int[m][n];
     7         int[][] reach = new int[m][n];
     8         int houseNum = 0;
     9         int[][] directions = {{-1,0},{1,0},{0,-1},{0,1}};
    10         
    11         for (int i=0; i<m; i++) {
    12             for (int j=0; j<n; j++) {
    13                 if (grid[i][j] == 1) {
    14                     houseNum++;
    15                     int level = 0;
    16                     boolean[][] visited = new boolean[m][n];
    17                     LinkedList<Integer> queue = new LinkedList<Integer>();
    18                     queue.offer(i*n+j);
    19                     visited[i][j] = true;
    20                     while (!queue.isEmpty()) {
    21                         int size = queue.size();
    22                         for (int t=0; t<size; t++) {
    23                             int cur = queue.poll();
    24                             int x = cur/n;
    25                             int y = cur%n;
    26                             for (int[] dir : directions) {
    27                                 int xnew = x + dir[0];
    28                                 int ynew = y + dir[1];
    29                                 if (xnew>=0 && xnew<m && ynew>=0 && ynew<n && !visited[xnew][ynew] && grid[xnew][ynew]==0) {
    30                                     queue.offer(xnew*n+ynew);
    31                                     visited[xnew][ynew] = true;
    32                                     dist[xnew][ynew] += level+1;
    33                                     reach[xnew][ynew]++;
    34                                 }
    35                             }
    36                         }
    37                         level++;
    38                     }
    39                 }
    40             }
    41         }
    42         
    43         int minDist = Integer.MAX_VALUE;
    44         for (int i=0; i<m; i++) {
    45             for (int j=0; j<n; j++) {
    46                 if (grid[i][j]==0 && reach[i][j] == houseNum) {
    47                     minDist = Math.min(minDist, dist[i][j]);
    48                 }
    49             }
    50         }
    51         return minDist==Integer.MAX_VALUE? -1 : minDist;
    52     }
    53 }
  • 相关阅读:
    numpy中linspace用法 (等差数列创建函数)
    Ubuntu环境下 matplotlib 图例中文乱码
    转载: 广义逆矩阵
    matplotlib.pyplot中add_subplot方法参数111的含义
    转载:(论文) 二次指数平滑法中确定初始值的简便方法
    图像处理之 opencv 学习---opencv 中的常用算法
    图像处理之 opencv 学习---矩阵的操作
    编译异常之static和extern---more than one storage class specified
    格式转换至yuv422转 yuv420
    阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_6 自定义类型转换器代码编写
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/5094091.html
Copyright © 2011-2022 走看看