leetcode The Maze I,II,III 详细总结

[LeetCode] 490. The Maze 迷宫

一:题意

链接:https://leetcode.com/articles/the-maze/
给定一个二维平面表示一个迷宫,迷宫中0代表空闲处,1代表墙,有一个人从start处可以上下左右四个方向移动(得朝着一个方向一直走到头,碰到墙才能换方向),碰到墙得换方向移动,问是否停在目的地destination。
经过目的地不算到达,球并不会停下来
边界已经用墙封住了,图中显示出了!
在这里插入图片描述

二:思路

  • dfs是不行的,超时了!
  • 使用bfs来做
    1:首先从start开始,作为起始节点
    2:扩展相邻结点,把上下左右四个方向走到尽头的坐标加入队列中
    3:直到遍历结束

三:实现

class Solution(object):
    def hasPath(self, maze, start, destination):
        if not maze: return False
        if start == destination: return True
        
        vis = set()
        m, n = len(maze), len(maze[0])
        
        dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]  # 四个方向
        queue = [(start[0], start[1])]  # 记录的是四个方向的尽头的坐标
        vis.add((start[0], start[1]))
        
        while queue:
            i, j = queue.pop()
            if i == destination[0] and j == destination[1]:
                return True
            
            for dis in dirs:  # 四个方向
                x = i + dis[0]
                y = j + dis[1]
                while 0 <= x < m and n <= y < n and maze[x][y] == 0: # 一直往一个方向走,直到撞墙
                    x += dis[0]
                    y += dis[1]
                
                # 要退一步,上一行的while循环多走了一步到墙里面了!
                x = x - dir[0]
                y = y - dir[1]
                
                # 到达尽头后,查看是否访问过
                if (x, y) not in vis:
                    vis.add((x, y))
                    queue = [(x, y)] + queue   # 先进先出为队列,BFS
        
        return False

[LeetCode] 505. The Maze II 迷宫之二

一:题意

地址:https://leetcode.com/articles/the-maze-ii/
题意与上一题一样,只是结果不是返回是否可到达目的地,而是到达目的地经历最短的路径。不存在路径返回-1

二:思路

  • dfs
  • bfs
    广度优先搜索,和上一题写法类似,只是记录一下到达坐标(x,y)的路径距离,而且不需要去重了(不需要vis=set()了),因为需要遍历多条路径。
    distance[i][j] 代表从开始位置到坐标 (i,j)的最短距离
    更新最短距离:if distance[i][j] + count < distance[x][y]
  • Dijkstra Algorithm

三:实现

  • dfs
class Solution(object):
    def shortestDistance(self, maze, start, destination):
        # 经过目的地不算,必须停留在目的地才行
        if not maze: return -1
        if start == destination: return 0
        
        distance = [[float('inf')]*n for i in range(m)]  # distance[i][j] 代表从开始位置到坐标 (i,j)的最短距离
        distance[start[0]][start[1]] = 0
          
        self.dfs(maze, start, distance)
        return distance[destination[0]][destination[1]] if distance[destination[0]][destination[1]] != float('inf') else -1
    
    def dfs(self, maze, start, distance):
        m, n = len(maze), len(maze[0])
        dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]  # 四个方向
        
        for dis in dirs:
            x = start[0] + dis[0]
            y = start[0] + dis[1]
            count = 0
            while 0 <= x < n and 0 <= y < m and maze[x][y] == 0:
                count += 1
                x += dis[0]
                y += dis[1]
                
            # 多走了一步啊,其实可以在while循坏中控制少走一步,改成maze[x+dis[0]][y+dis[1]] == 0就行
            count -= 1
            x = x - dir[0]
            y = y - dir[1]

            if distance[i][j] + count < distance[x][y]:  # 更新最短距离
                distance[x][y] = distance[i][j] + count
                self.dfs(maze, [x, y], distance)
  • bfs
class Solution(object):
    def shortestDistance(self, maze, start, destination):
        # 经过目的地不算,必须停留在目的地才行
        
        if not maze: return -1
        if start == destination: return 0
        
        m, n = len(maze), len(maze[0])
        distance = [[float('inf')]*n for i in range(m)]  # distance[i][j] 代表从开始位置到坐标 (i,j)的最短距离
        distance[start[0]][start[1]] = 0
        
        dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]  # 四个方向
        queue = [(start[0], start[1])]  # 记录的是四个方向的尽头的坐标
        
        while queue:
            i, j = queue.pop()
            for dis in dirs:
                count = 0
                x = i + dis[0]
                y = j + dis[1]
                
                while 0 <= x < n and 0 <= y < m and maze[x][y] == 0:
                    count += 1
                    x += dis[0]
                    y += dis[1]
                
                # 多走了一步啊,其实可以在while循坏中控制少走一步,改成maze[x+dis[0]][y+dis[1]] == 0就行
                count -= 1
                x = x - dir[0]
                y = y - dir[1]
                
                if distance[i][j] + count < distance[x][y]:  # 更新最短距离
                    queue = [(x, y)] + queue
                    distance[x][y] = distance[i][j] + count
        
        return distance[destination[0]][destination[1]] if distance[destination[0]][destination[1]] != float('inf') else -1

[LeetCode] 499 The Maze III 迷宫之三

一:题意

在路径中间放了个陷阱,让球在最小步数内滚到陷阱之中,此时返回的并不是最小步数,而是滚动的方向,用u, r, d, l 这四个字母来分别表示上右下左,而且在步数相等的情况下,让我们返回按字母排序小的答案。
这题只要经过陷阱就行,而不是停留在陷阱处。

二:思路

三:实现

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值