题目描述:
The Maze III 是 LeetCode 上的一道中等难度的题目,编号为 499。题目描述如下:
有一个迷宫,由 m x n
的二维网格表示。网格中有空地(用 表示)和墙壁(用
1
表示)。此外,迷宫中有一个球,球的初始位置为 (startrow, startcol)
,目标位置为 (goalrow, goalcol)
。
球可以沿着四个方向(上、下、左、右)滚动,但每次滚动都会一直滚到遇到墙壁或边界为止。你需要找到球从初始位置滚到目标位置的最短路径,并返回这条路径。如果有多条最短路径,返回字典序最小的那条。
输入:
maze
: 迷宫的二维数组startrow
,startcol
: 球的初始位置goalrow
,goalcol
: 目标位置
输出:
- 字符串,表示球从初始位置到目标位置的最短路径,路径由
'u'
(上)、'd'
(下)、'l'
(左)、'r'
(右)组成。
示例:
输入:
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]
]
startrow = 0, startcol = 4
goalrow = 4, goalcol = 4
输出: "dldr"
解题思路:
-
BFS(广度优先搜索):
- 使用 BFS 来遍历迷宫,记录每个位置到达的最短路径和路径长度。
- 使用优先队列(最小堆)来保证字典序最小的路径优先被处理。
-
DFS(深度优先搜索):
- 使用 DFS 来遍历迷宫,记录每个位置到达的最短路径和路径长度。
- 需要使用额外的数据结构来记录已访问的位置和路径长度,以避免重复遍历。
-
Dijkstra 算法:
- 使用 Dijkstra 算法来找到最短路径,同时维护路径的字典序。
具体实现步骤(BFS 方法):
- 初始化一个优先队列,存储
(路径长度, 当前位置, 路径)
的三元组。 - 将初始位置
(0, startrow, startcol, "")
加入优先队列。 - 使用一个字典
visited
来记录每个位置的最短路径长度和字典序最小的路径。 - 从优先队列中取出当前状态,更新
visited
。 - 沿四个方向滚动球,计算新的位置和路径,如果新位置更优,则加入优先队列。
- 重复步骤 4 和 5,直到找到目标位置。
Python 代码示例:
from heapq import heappop, heappush
from collections import defaultdict
def shortestDistance(maze, startrow, startcol, goalrow, goalcol): m, n = len(maze), len(maze[0]) directions = [(-1, 0, 'u'), (1, 0, 'd'), (0, -1, 'l'), (0, 1, 'r')] visited = defaultdict(lambda: float('inf')) pq = [(0, startrow, startcol, "")]
while pq:
dist, x, y, path = heappop(pq)
if (x, y) == (goalrow, goalcol):
return path
if dist > visited[(x, y)]:
continue
visited[(x, y)] = dist
for dx, dy, d in directions:
nx, ny, step = x, y, 0
while 0 <= nx + dx < m and 0 <= ny + dy < n and maze[nx + dx][ny + dy] == 0:
nx += dx
ny += dy
step += 1
if dist + step < visited[(nx, ny)]:
visited[(nx, ny)] = dist + step
heappush(pq, (dist + step, nx, ny, path + d))
return ""
示例输入
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] ] startrow = 0 startcol = 4 goalrow = 4 goalcol = 4
调用函数
print(shortestDistance(maze, startrow, startcol, goalrow, goalcol)) # 输出: "dldr"
解释:
- 使用优先队列
pq
来存储当前的状态(路径长度, 当前位置, 路径)
,保证字典序最小的路径优先被处理。 - 使用
visited
字典来记录每个位置的最短路径长度,避免重复遍历。 - 沿四个方向滚动球,计算新的位置和路径,如果新位置更优,则加入优先队列。
- 最终找到目标位置时,返回对应的路径。
希望这个详细的解答能帮助你理解并解决 The Maze III 这道题目。如果有任何进一步的问题,欢迎继续提问!
发表回复