寻路机器人单片机程序示例_Leedcode 面试题 08.02. 迷路的机器人 题解

a619fcf77b463f7e9cca2ce00a4aa562.png

题目链接:Leedcode 面试题 08.02. 迷路的机器人 题解

设想有个机器人坐在一个网格的左上角,网格 r 行 c 列。机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)。设计一种算法,寻找机器人从左上角移动到右下角的路径。

b471916a202b10d67b0ea650fd0ca606.png
迷路机器人示意图

网格中的障碍物和空位置分别用 1 和 0 来表示。

返回一条可行的路径,路径由经过的网格的行号和列号组成。左上角为 0 行 0 列。如果没有可行的路径,返回空数组。

示例 1:

输入:

[

[0,0,0],

[0,1,0],

[0,0,0]

]

输出: [[0,0],[0,1],[0,2],[1,2],[2,2]]

解释:

输入中标粗的位置即为输出表示的路径,即

0行0列(左上角) -> 0行1列 -> 0行2列 -> 1行2列 -> 2行2列(右下角)

说明:r 和 c 的值均不超过 100。

来源:力扣(LeetCode)

链接:面试题 08.02. 迷路的机器人

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

462ef33e362dd329cb8577cd984d997f.png
题解的时空效率

解题链接:动态规划法 + 唯一策略寻路递归

解题思路

从左上角到右下角,机器人只需要向下或者向右走就可以了。

1.定义dp=[]数组元素含义:

棋盘上每一个地方,都有三种可能:

a. 不可能通过此地。

b. 自左通过此地。

c. 自上通过此地。

为了保证路径的唯一性,我们规定当既可以自上又可以自左通过此处时,自左通过此地的情况优先进入决策。

2.找出初始值:

网格的最上边可通过的每一格唯一只能从左通过:

        for i in range(len_x):
            if obstacleGrid[0][i] == 1:
                break
            dp[0][i] = 0

网格的最左边可通过的每一格唯一只能从上通过:

        for i in range(1,len_y):
            if obstacleGrid[i][0] == 1:
                break
            dp[i][0] = 1

3.找出状态转移方程:

自1到len_x遍历,自1到len_y遍历:

                if obstacleGrid[y][x] == 1:
                    continue
                elif dp[y][x-1] != -1:
                    dp[y][x] = 0
                    continue
                elif dp[y-1][x] != -1:
                    dp[y][x] = 1

4.得到dp的二维数组后,根据dp和自左优先策略倒叙逐步添加坐标来得出唯一的路径

输出的时候反转path数组。

代码

class Solution:
    def pathWithObstacles(self, obstacleGrid: List[List[int]]) -> List[List[int]]:
        if not obstacleGrid or obstacleGrid[0][0] == 1:
            return []
        len_x = len(obstacleGrid[0])
        len_y = len(obstacleGrid)
        dp = [[-1]*len_x for _ in range(len_y)]
        # 不可通过 dp = -1
        # 自左通过 dp = 0 优先考虑
        # 自上通过 dp = 1
        for i in range(len_x):
            if obstacleGrid[0][i] == 1:
                break
            dp[0][i] = 0
        for i in range(1,len_y):
            if obstacleGrid[i][0] == 1:
                break
            dp[i][0] = 1
        for x in range(1,len_x):
            for y in range(1,len_y):
                if obstacleGrid[y][x] == 1:
                    continue
                elif dp[y][x-1] != -1:
                    dp[y][x] = 0
                    continue
                elif dp[y-1][x] != -1:
                    dp[y][x] = 1
        if dp[-1][-1] == -1:
            return []
        path = []
        self.addpath(len_x-1,len_y-1,dp,path)
        return path[::-1]

    def addpath(self,x,y,dp,path):
        if x<0 or y<0:
            return
        if dp[y][x] == 0:
            path.append([y,x])
            self.addpath(x-1,y,dp,path)
        elif dp[y][x] == 1:
            path.append([y,x])
            self.addpath(x,y-1,dp,path)
        else:
            return

作者:zkw-r

链接:动态规划法 + 唯一策略寻路递归

来源:力扣(LeetCode)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参考1:告别动态规划,连刷40道动规算法题,我总结了动规的套路

参考2:入门DP题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值