LeetCode-Shortest Distance from All Buildings

LiBlog發表於2016-07-21

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.

Analysis:

Simply BFS on every building point.

 

Solution:

 1 public class Solution {
 2     public void addPointToQueue(int[][] grid, int[][] sum, int[][] dis, boolean[][] visited, int curDis,
 3             int nextX, int nextY, Queue<Point> q) {
 4         int row = sum.length;
 5         int col = sum[0].length;
 6         if (nextX < 0 || nextX >= row || nextY < 0 || nextY >= col || visited[nextX][nextY] || grid[nextX][nextY] > 0) {
 7             return;
 8         }
 9 
10         visited[nextX][nextY] = true;
11         dis[nextX][nextY] = curDis + 1;
12         q.add(new Point(nextX, nextY));
13 
14         sum[nextX][nextY] += curDis + 1;
15     }
16 
17     public void BuildingUpdate(int[][] grid, int[][] sum, boolean[][] allReachable, Point start) {
18         int row = grid.length;
19         int col = grid[0].length;
20         int[][] dis = new int[row][col];
21         boolean[][] visited = new boolean[row][col];
22 
23         Queue<Point> q = new LinkedList<Point>();
24         q.add(start);
25         while (!q.isEmpty()) {
26             Point cur = q.poll();
27             int d = dis[cur.x][cur.y];
28 
29             addPointToQueue(grid, sum, dis, visited, d, cur.x - 1, cur.y, q);
30             addPointToQueue(grid, sum, dis, visited, d, cur.x + 1, cur.y, q);
31             addPointToQueue(grid, sum, dis, visited, d, cur.x, cur.y - 1, q);
32             addPointToQueue(grid, sum, dis, visited, d, cur.x, cur.y + 1, q);
33         }
34 
35         // Check reachability
36         for (int i = 0; i < row; i++)
37             for (int j = 0; j < col; j++)
38                 if (!visited[i][j]) {
39                     allReachable[i][j] = false;
40                 }
41     }
42 
43     public int shortestDistance(int[][] grid) {
44         if (grid.length == 0 || grid[0].length == 0)
45             return -1;
46 
47         int row = grid.length;
48         int col = grid[0].length;
49         int[][] sum = new int[row][col];
50         boolean[][] allReachable = new boolean[row][col];
51         for (int i = 0; i < row; i++) {
52             Arrays.fill(allReachable[i], true);
53         }
54 
55         for (int i = 0; i < row; i++)
56             for (int j = 0; j < col; j++)
57                 if (grid[i][j] == 1) {
58                     BuildingUpdate(grid, sum, allReachable, new Point(i, j));
59                 }
60 
61         int res = Integer.MAX_VALUE;
62         for (int i = 0; i < row; i++)
63             for (int j = 0; j < col; j++)
64                 if (allReachable[i][j]) {
65                     res = Math.min(res, sum[i][j]);
66                 }
67 
68         if (res == Integer.MAX_VALUE)
69             return -1;
70         return res;
71     }
72 }

Note: the code can be shorter, just I like this which makes the code clear and organized.

相關文章