问题描述:
你想在空旷的土地上建造一座房子,以最短的距离到达所有建筑物。您只能向上,向下,向左和向右移动。您将获得值为0,1或2的2D网格,其中:
每个0都标志着一片空地,你可以自由地经过。 每1个标记一个您无法通过的建筑物。 每个2都标志着你无法通过的障碍。 例如,给定(0,0),(0,4),(2,2)处的三个建筑物和(0,2)处的障碍物:
1 - 0 - 2 - 0 - 1
| | | | |
0 - 0 - 0 - 0 - 0
| | | | |
0 - 0 - 1 - 0 - 0
点(1,2)是建造房屋的理想空地,因为3 + 3 + 1 = 7的总行程距离是最小的。所以返回7。
我用BFS方式解决了这个问题。然后我想用DFS方式解决它,但卡住了。以下是我的代码:
class Solution(object):
def shortestDistance(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
rl, cl = len(grid), len(grid[0])
builds = sum([col for row in grid for col in row if col == 1])
dist, hit = [[0] * cl for _ in range(rl)], [[0] * cl for _ in range(rl)]
def dfs(x, y, step):
'''
Wrong answer, it seems result dist alway keep the longest distance?
'''
if 0 <= x < rl and 0 <= y < cl and not visited[x][y]:
visited[x][y] = True
if grid[x][y] == 0:
dist[x][y] += (step + 1)
hit[x][y] += 1
dfs(x - 1, y, step + 1)
dfs(x + 1, y, step + 1)
dfs(x, y - 1, step + 1)
dfs(x, y + 1, step + 1)
def bfs(x, y):
'''
works properly
'''
visited = [[False] * cl for _ in range(rl)]
queue =[(x, y, 0)]
while queue:
k, m, step = queue.pop(0)
for i, j in ((k - 1, m), (k + 1, m), (k, m - 1), (k, m + 1)):
if 0 <= i < rl and 0 <= j < cl and not visited[i][j]:
visited[i][j] = True
if grid[i][j] == 0:
dist[i][j] += (step + 1)
hit[i][j] += 1
queue.append((i, j, step + 1))
for i in range(rl):
for j in range(cl):
if grid[i][j] == 1:
# bfs(i, j) # this works properly
visited = [[False] * cl for _ in range(rl)]
dfs(i - 1, j, 0)
dfs(i + 1, j, 0)
dfs(i, j - 1, 0)
dfs(i, j + 1, 0)
ret = float('inf')
for i in range(rl):
for j in range(cl):
if grid[i][j] == 0 and hit[i][j] == builds:
ret = min(ret, dist[i][j])
return ret if ret != float('inf') else -1
# expect 7
print Solution().shortestDistance([[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]])
这是一种典型的图搜索问题。通常可以用DFS和BFS方式解决。只是无法弄清楚如何以DFS方式修复它?
答案 0 :(得分:0)
简单DFS并非旨在找到最短路径。通过一些回溯和谨慎的标记以及对被访问节点的取消标记,您可以使用它来查找到达给定点的所有路径并选择最短路径,但它不必要地复杂且比BFS慢。