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.
Similar :
- 286. Walls and Gates
- 296. Best Meeting Point
1 public class Solution { 2 public int shortestDistance(int[][] grid) { 3 if (grid.length==0 || grid[0].length==0) 4 return 0; 5 6 int m = grid.length; 7 int n = grid[0].length; 8 int[][] dist = new int[m][n]; 9 int[][] reach = new int[m][n]; 10 final int[] shift = {1, 0, -1, 0, 1}; 11 int bldNum = 0; 12 13 for (int i = 0; i < m; i++) 14 for (int j = 0; j < n; j++) { 15 if (grid[i][j] == 1) { 16 bldNum++; 17 18 Queue<int[]> queue = new LinkedList<int[]>(); 19 queue.offer(new int[] {i,j}); 20 boolean[][] visit = new boolean[m][n]; 21 int level = 1; 22 while (!queue.isEmpty()) { 23 int size = queue.size(); 24 for (int k=0; k<size; k++) { 25 int[] pt = queue.poll(); 26 27 for (int l = 0; l < 4; l++) { 28 int row = pt[0] + shift[l]; 29 int col = pt[1] + shift[l+1]; 30 if (row >= 0 && row < m && col >= 0 && col < n && grid[row][col] == 0 && !visit[row][col]) { 31 dist[row][col] += level; 32 reach[row][col]++; 33 visit[row][col] = true; 34 queue.offer(new int[] {row,col}); 35 } 36 } 37 38 } 39 level++; 40 } 41 } 42 } 43 44 int shortest = Integer.MAX_VALUE; 45 for (int i = 0; i < m; i++) 46 for(int j = 0; j < n; j++) { 47 if (grid[i][j] == 0 && reach[i][j] == bldNum) { 48 shortest = Math.min(shortest, dist[i][j]); 49 } 50 } 51 52 return shortest == Integer.MAX_VALUE ? -1 : shortest; 53 } 54 }