|
| 1 | +''' |
| 2 | +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: |
| 3 | +
|
| 4 | +Each 0 marks an empty land which you can pass by freely. |
| 5 | +Each 1 marks a building which you cannot pass through. |
| 6 | +Each 2 marks an obstacle which you cannot pass through. |
| 7 | +For example, given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2): |
| 8 | +
|
| 9 | +1 - 0 - 2 - 0 - 1 |
| 10 | +| | | | | |
| 11 | +0 - 0 - 0 - 0 - 0 |
| 12 | +| | | | | |
| 13 | +0 - 0 - 1 - 0 - 0 |
| 14 | +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. |
| 15 | +
|
| 16 | +Note: |
| 17 | +There will be at least one building. If it is not possible to build such house according to the above rules, return -1. |
| 18 | +''' |
| 19 | + |
| 20 | + |
| 21 | +class Solution(object): |
| 22 | +def shortestDistance(self, grid): |
| 23 | +if not grid: |
| 24 | +return -1 |
| 25 | + |
| 26 | +def bfs(grid, distance_reach_map, row, col): |
| 27 | +if(row < 0 or row > len(grid) or col < 0 or col > len(grid[0])): |
| 28 | +return |
| 29 | +queue = [[row, col]] |
| 30 | +qdist = [1] |
| 31 | + |
| 32 | +direction = [[-1, 0], [0, 1], [1, 0], [0, -1]] |
| 33 | +while queue: |
| 34 | +x, y = queue.pop(0) |
| 35 | +curr_dist = qdist.pop(0) |
| 36 | + |
| 37 | +for dx, dy in direction: |
| 38 | +new_x, new_y = x+dx, y+dy |
| 39 | +if((0 <= new_x < len(grid)) and (0 <= new_y < len(grid[0])) and grid[new_x][new_y] == 0): |
| 40 | +grid[new_x][new_y] = -1 |
| 41 | +queue.append([new_x, new_y]) |
| 42 | + |
| 43 | + |
| 44 | +temp = distance_reach_map[new_x][new_y] |
| 45 | +dist, reach = temp[0], temp[1] |
| 46 | +dist += curr_dist |
| 47 | +reach += 1 |
| 48 | +distance_reach_map[new_x][new_y] = [dist, reach] |
| 49 | +qdist.append(curr_dist+1) |
| 50 | + |
| 51 | +for row in range(len(grid)): |
| 52 | +for col in range(len(grid[0])): |
| 53 | +if grid[row][col] == -1: |
| 54 | +grid[row][col] =0 |
| 55 | + |
| 56 | +r_len, c_len = len(grid), len(grid[0]) |
| 57 | +distance_reach_map = [[[0, 0]]*c_len for _ in range(r_len)] |
| 58 | +buildings = 0 |
| 59 | +for row in range(len(grid)): |
| 60 | +for col in range(len(grid[0])): |
| 61 | +if grid[row][col] == 1: |
| 62 | +bfs(grid, distance_reach_map, row, col) |
| 63 | +buildings += 1 |
| 64 | + |
| 65 | +result = float('inf') |
| 66 | +for row in range(r_len): |
| 67 | +for col in range(c_len): |
| 68 | +dist, reach = distance_reach_map[row][col] |
| 69 | +if reach == buildings: |
| 70 | +result = min(result, dist) |
| 71 | +return result |
| 72 | + |
| 73 | +solution = Solution() |
| 74 | +grid = [[1, 0, 2, 0, 1], |
| 75 | +[0, 0, 0, 0, 0], |
| 76 | +[0, 0, 1, 0 ,0]] |
| 77 | +print solution.shortestDistance(grid) |
| 78 | + |
| 79 | + |
| 80 | + |
| 81 | + |
| 82 | + |
0 commit comments