|
3 | 3 | ## do BFS from each building, and decrement all empty place for every building visit
|
4 | 4 | ## when grid[i][j] == -b_nums, it means that grid[i][j] are already visited from all b_nums
|
5 | 5 | ## and use dist to record distances from b_nums
|
6 |
| - |
7 | 6 | def shortest_distance(grid):
|
8 |
| - """ |
9 |
| - :type grid: List[List[int]] |
10 |
| - :rtype: int |
11 |
| - """ |
12 |
| - m = len(grid) |
13 |
| - n = len(grid[0]) |
14 |
| - if not m or not n: |
| 7 | + if not grid or not grid[0]: |
15 | 8 | return -1
|
16 | 9 |
|
17 |
| - dist = [[0] * n] * m |
18 |
| - b_nums = 0 |
19 |
| - for i in range(m): |
20 |
| - for j in range(n): |
21 |
| - if grid[i][j]==1: b_nums+=1 |
22 |
| - b_idx = 0 |
23 |
| - for i in range(m): |
24 |
| - for j in range(n): |
25 |
| - if grid[i][j]==1: |
26 |
| - bfs(grid, dist, i, j, b_idx) |
27 |
| - b_idx -= 1 |
28 |
| - res = [] |
29 |
| - for i in range(m): |
30 |
| - for j in range(n): |
31 |
| - if grid[i][j] + b_nums == 0: |
32 |
| - res.append(dist[i][j]) |
33 |
| - return min(res) if res else -1 |
| 10 | + matrix = [[[0,0] for i in range(len(grid[0]))] for j in range(len(grid))] |
| 11 | + |
| 12 | + cnt = 0 # count how many building we have visited |
| 13 | + for i in range(len(grid)): |
| 14 | + for j in range(len(grid[0])): |
| 15 | + if grid[i][j] == 1: |
| 16 | + bfs([i,j], grid, matrix, cnt) |
| 17 | + cnt += 1 |
| 18 | + |
| 19 | + res = float('inf') |
| 20 | + for i in range(len(matrix)): |
| 21 | + for j in range(len(matrix[0])): |
| 22 | + if matrix[i][j][1]==cnt: |
| 23 | + res = min(res, matrix[i][j][0]) |
34 | 24 |
|
35 |
| -def bfs(grid, dist, i, j, b_idx): |
36 |
| - m = len(grid) |
37 |
| - n = len(grid[0]) |
38 |
| - queue = collections.deque([(i, j, 0)]) |
39 |
| - while queue: |
40 |
| - i, j, d = queue.popleft() |
41 |
| - for x,y in [(i+1, j), (i-1, j), (i, j-1), (i, j+1)]: |
42 |
| - if 0<=x<m and 0<=y<n and grid[x][y] == b_idx: |
43 |
| - dist[x][y] += d+1 |
44 |
| - grid[x][y] -= 1 |
45 |
| - queue.append((x, y, d+1)) |
| 25 | + return res if res!=float('inf') else -1 |
46 | 26 |
|
| 27 | +def bfs(start, grid, matrix, cnt): |
| 28 | + q = [(start, 0)] |
| 29 | + while q: |
| 30 | + tmp = q.pop(0) |
| 31 | + po, step = tmp[0], tmp[1] |
| 32 | + for dp in [(-1,0), (1,0), (0,1), (0,-1)]: |
| 33 | + i, j = po[0]+dp[0], po[1]+dp[1] |
| 34 | + # only the position be visited by cnt times will append to queue |
| 35 | + if 0<=i<len(grid) and 0<=j<len(grid[0]) and matrix[i][j][1]==cnt and grid[i][j]==0: |
| 36 | + matrix[i][j][0] += step+1 |
| 37 | + matrix[i][j][1] = cnt+1 |
| 38 | + q.append(([i,j], step+1)) |
47 | 39 |
|
48 | 40 | grid = [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]]
|
49 | 41 | print(shortest_distance(grid))
|
0 commit comments