📜  二进制迷宫中的最短路径(1)

📅  最后修改于: 2023-12-03 15:36:04.170000             🧑  作者: Mango

二进制迷宫中的最短路径

简介

二进制迷宫是一种用 0 和 1 表示障碍和通路的迷宫。在二进制迷宫中寻找最短路径是一个常见的面试题和算法题目,它也有很多现实生活中的应用场景,如机器人避障、路线规划等。

一般可采用广度优先搜索和 Dijkstra 最短路径算法来解决这个问题。

广度优先搜索算法解题思路

广度优先搜索(BFS)是一种图的遍历算法,它从起点开始搜索,先将其相邻且未被访问的结点入队,每次取出队列头结点继续搜索,直至到达终点或搜索全部结点。

在二进制迷宫中,BFS 算法从起点开始搜索,访问其相邻的通路结点并标记它们为已访问,直到找到终点(若存在),则输出对应的最短路径。

下面是 BFS 的 Python 代码实现:

from collections import deque

def shortestPath(maze, start, end):
    m, n = len(maze), len(maze[0])
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]  # 上下左右四个方向
    q = deque([(start[0], start[1], 0)])  # (i, j, steps)
    visited = {(start[0], start[1])}
    while q:
        i, j, steps = q.popleft()
        if i == end[0] and j == end[1]:
            return steps  # 返回最短路径的步数
        for dx, dy in directions:
            x, y = i + dx, j + dy
            if 0 <= x < m and 0 <= y < n and maze[x][y] == 0 and (x, y) not in visited:
                q.append((x, y, steps + 1))
                visited.add((x, y))
    return -1  # 无法抵达目的地

其中,maze 为一个二维数组,0 表示通路,1 表示障碍;startend 分别是起点和终点的坐标,visited 是记录已访问过的结点的集合。

Dijkstra 最短路径算法解题思路

Dijkstra 最短路径算法是一种贪心算法,广泛用于求带权图中从一个结点出发到其它结点的最短路径。它通过维护一个结点集合和一个距离集合,不断更新距离集合中的最小值来求出最短路径。

在二进制迷宫中,Dijkstra 算法从起点开始搜索,初始化距离集合,通过查找最小距离结点将其加入集合中,并更新与它相邻的结点的距离值,直到找到终点(若存在),则输出对应的最短路径。

下面是 Dijkstra 的 Python 代码实现:

import heapq  # 优先队列

def shortestPath(maze, start, end):
    m, n = len(maze), len(maze[0])
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]  # 上下左右四个方向
    heap = [(0, start[0], start[1])]
    dist = {(i, j): float('inf') for i in range(m) for j in range(n)}
    dist[start] = 0
    while heap:
        steps, i, j = heapq.heappop(heap)
        if dist[(i, j)] < steps:
            continue
        if i == end[0] and j == end[1]:
            return steps  # 返回最短路径的步数
        for dx, dy in directions:
            x, y = i + dx, j + dy
            if 0 <= x < m and 0 <= y < n and maze[x][y] == 0 and dist[(x, y)] > dist[(i, j)] + 1:
                dist[(x, y)] = dist[(i, j)] + 1
                heapq.heappush(heap, (dist[(x, y)], x, y))
    return -1  # 无法抵达目的地

其中,heap 是一个优先队列,用于存储距离,dist 是一个字典,用于存储距离值。

总结

二进制迷宫是一个常见的算法题目,可以通过广度优先搜索和 Dijkstra 最短路径算法来解决。这两种算法的时间复杂度均为 $O(mn)$,其中 $m$ 和 $n$ 分别为迷宫的行数和列数。在实际应用中,Dijkstra 算法一般用于求带权有向图的最短路径,比 BFS 更加高效。

完整代码可以参考 LeetCode 1091. Shortest Path in Binary Matrix