📅  最后修改于: 2023-12-03 15:42:20.372000             🧑  作者: Mango
对于一个表示由若干道门所连接的两个房间的迷宫,我们可以使用二维数组 maze 表示,其中 maze[i][j] 为 0 表示该位置可以到达,maze[i][j] 为 1 表示该位置不可到达。请你计算从起点 start 到终点 destination 最少需要几步。
如果无法到达终点,请返回 -1。
注意:
输入:
maze = [[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 1, 0],
[1, 1, 0, 1, 1],
[0, 0, 0, 0, 0]],
start = [0, 4], destination = [4, 4]
输出: 12
解释: 我们可以寻找以下路径来到达终点:
左 -> 下 -> 下 -> 左 -> 左 -> 下 -> 下 -> 右 -> 右 -> 下 -> 下 -> 右。
总步数为 12。
由于需要求从一个点到另一个点的最短路径,自然想到使用 BFS 算法。
我们从起点开始,并将其加入到队列中。然后在每一步中,我们取队列首部的节点,并考虑一下所有可以到达的相邻节点。若该相邻节点在迷宫中没有被访问过(也就是没有走过),我们对该节点进行标记并将其加入队列中,并且记录一下步数。若在某一时刻,我们找到了终点,那么我们就可以直接返回或者在 BFS 过程中使用一些剪枝技巧来加速搜索。最后,若我们到达了队列为空,那么就说明从起点无法到达终点。
以下是 Python 3 语言的解题代码实现:
class Solution:
def shortestDistance(self, maze: List[List[int]], start: List[int], destination: List[int]) -> int:
ROW, COL = len(maze), len(maze[0])
visited = set()
queue = collections.deque([(start[0], start[1], 0)])
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
while queue:
x, y, steps = queue.popleft()
if [x, y] == destination:
return steps
if (x, y) in visited:
continue
visited.add((x, y))
for dx, dy in directions:
nx, ny = x, y
# 向一个方向走到尽头
while 0 <= nx + dx < ROW and 0 <= ny + dy < COL and maze[nx + dx][ny + dy] == 0:
nx += dx
ny += dy
if (nx, ny) not in visited:
queue.append((nx, ny, steps + abs(nx - x) + abs(ny - y)))
return -1
其中,我们使用了集合 visited 存储走过的位置,使用队列 queue 来进行 BFS,并使用 directions 列出可能的方向(向上走、向下走、向左走、向右走)。最后,也就是找到终点 destination,我们返回最短距离 steps。