The Maze,LeetCode,490

题目描述

由空地和墙组成的迷宫中有一个球。球可以向上(u)、下(d)、左(l)或右(r)四个方向滚动,但在遇到墙壁前不会停止滚动。当球停下时,可以选择下一个方向。迷宫中有一个终点,当球到达终点时,游戏结束。

给定迷宫的二维网格,其中 1 表示墙壁, 表示空地,以及球的起始位置和终点位置,请判断球能否到达终点。

示例

输入 1: 迷宫由以下二维数组表示

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

输入 2: 球的初始位置 (rowStart, colStart) = (0, 4) 输入 3: 球的终点位置 (rowEnd, colEnd) = (4, 4)

输出: true

解释: 球可以按照如下路径从起点滚到终点: (0, 4) -> (0, 3) -> (1, 3) -> (1, 2) -> (1, 1) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) -> (3, 2) -> (4, 2) -> (4, 3) -> (4, 4)

解题思路

  1. 深度优先搜索(DFS)
    • 从起始位置开始,尝试四个方向滚动。
    • 每个方向上,球会一直滚动直到遇到墙壁或边界。
    • 到达新位置后,递归地继续搜索。
    • 如果到达终点,返回 true
    • 使用一个集合记录已经访问过的位置,避免重复搜索。
  2. 广度优先搜索(BFS)
    • 使用队列存储待访问的位置。
    • 从起始位置开始,将四个方向上的可行位置加入队列。
    • 每次从队列中取出一个位置,检查是否到达终点。
    • 如果到达终点,返回 true
    • 否则,继续将新位置加入队列。

代码实现(DFS)

def hasPath(maze, start, destination): def dfs(maze, start, destination, visited): if start == destination: return True visited.add(start) directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] for dx, dy in directions: x, y = start while 0 <= x + dx < len(maze) and 0 <= y + dy < len(maze[0]) and maze[x + dx][y + dy] == 0: x += dx y += dy if (x, y) not in visited and dfs(maze, (x, y), destination, visited): return True return False

visited = set()
return dfs(maze, tuple(start), tuple(destination), visited)

示例输入

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]

调用函数

print(hasPath(maze, start, destination)) # 输出: True

代码实现(BFS)

from collections import deque

def hasPath(maze, start, destination): queue = deque([tuple(start)]) visited = set([tuple(start)]) directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]

while queue:
    x, y = queue.popleft()
    if (x, y) == tuple(destination):
        return True
    for dx, dy in directions:
        nx, ny = x, y
        while 0 <= nx + dx < len(maze) and 0 <= ny + dy < len(maze[0]) and maze[nx + dx][ny + dy] == 0:
            nx += dx
            ny += dy
        if (nx, ny) not in visited:
            visited.add((nx, ny))
            queue.append((nx, ny))
return False

示例输入

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]

调用函数

print(hasPath(maze, start, destination)) # 输出: True

总结

  • DFS 适合于路径搜索,但可能会遇到深度很大的情况,导致栈溢出。
  • BFS 适合于寻找最短路径,且不会因为深度过大而出现问题,但需要更多的空间来存储队列。

根据具体问题的需求选择合适的算法。在这个迷宫问题中,两种方法都可以有效解决。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注