📅  最后修改于: 2023-12-03 14:58:33.679000             🧑  作者: Mango
给定一个由 '0' 和 '1' 组成的矩阵,其中 '0' 表示通道,'1' 表示墙壁,找到从矩阵中某一门到达另一扇门的最短路线。门用 'M' 标识。
每一步可以往上、下、左、右移动。您可以假设矩阵的四个边框均为墙。
如果找不到这样一条路径,则返回 -1。
例如,给定以下矩阵:
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 1],
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 1],
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 1],
['M', 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 'M', 0, 0],
[0, 0, 0, 0, 1],
]
其中,两个门为 'M',一个矩阵可视为:
从左下角的门(下图右下角)到右上角的门(下图左上角)的最短路径是 10
步。
广度优先算法是一种遍历图或树的算法,从根节点开始, 沿着宽度遍历节点, 如果这个节点没有被遍历过, 那么将它的所有邻居节点加入遍历的队列中,并标记为已遍历。
在本题中,使用广度优先算法可以寻找一条从起点到终点的最短路径。
def find_path(maze):
"""
:type maze: List[List[int]]
:rtype: int
"""
if not maze or not maze[0]:
return -1
directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
m, n = len(maze), len(maze[0])
def bfs(queue):
steps = 0
while queue:
steps += 1
for _ in range(len(queue)):
x, y = queue.pop(0)
for dx, dy in directions:
nx, ny = x + dx, y + dy
if 0 <= nx < m and 0 <= ny < n and maze[nx][ny] != 1 and not visited[nx][ny]:
if maze[nx][ny] == "M":
return steps
else:
queue.append((nx, ny))
visited[nx][ny] = True
return -1
maze = [[1] * (n + 2)] + [[1] + r + [1] for r in maze] + [[1] * (n + 2)]
visited = [[False] * (n + 2) for _ in range(m + 2)]
start, end = None, None
for i in range(1, m + 1):
for j in range(1, n + 1):
if maze[i][j] == "M":
if not start:
start = (i, j)
else:
end = (i, j)
return bfs([start]) if start and end else -1