|
| 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