LeetCode算法题之63. Unique Paths II(Medium)【Python3题解】

本文详细解析了LeetCode算法题63题——Unique Paths II的独特解法,重点介绍了如何在存在障碍物的网格中寻找从起点到终点的路径数量,通过动态规划算法巧妙地处理障碍物限制。

题目描述:
A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).

Now consider if some obstacles are added to the grids. How many unique paths would there be?
在这里插入图片描述
Example 1:

Input:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
Output: 2

Explanation:
There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:

  1. Right -> Right -> Down -> Down
  2. Down -> Down -> Right -> Right

题目大意:

  • 还是那句话,有II必有I,还是先看I:LeetCode算法题之62. Unique Paths(medium)【Python3题解】
  • II与I的不同之处就在于,I只给你了行和列的整数值,用m,n代替,这次给定你一个数组,格子的大小就是数组的大小,数组里面的数代表每个格子的位置上面的数,如果为0,代表可以走,如果为1,那就是障碍,过不去

解题思路:

  • II无非就是加入了障碍的限制,用数组中的1代表,想一下,如果数组中的数全部是0,那不就是I了吗,思路想法照搬即可
  • 现在的情况是,因为数组中会有1出现,而且你不知道在哪,有1,代表有障碍,你过不去。之前的思路是,有一张dp table,你把它填好就行了,dp 数组的最后一个元素就是答案
  • 之前的时候,你是怎么填那个表的?因为没有限制啊,所以第0行和第0列,你都可以直接填1啊,代表到达那个位置只有这一条路径可走
  • 现在有了数组中有了障碍,如果遇到1,你就过不去了,过不去了,那就填充0好了,代表到达这个位置时,没有路径可走
  • 如果遇到0,就是通畅的,填充1就好了,其余的位置的算法与I一样,都是那个位置的左边的数加上上边的数
  • 亲测,这样不行,还没完
  • 根据报错出来的案例一看,就知道,如果你遇到0,就填充1,这样不对,如果你遇到0时候,你前一个位置是1呢?你根本没有路可以走啊,你怎么能填1呢?
  • 所以解决办法是,当遇到数组中的0时,如果前一个位置数组中是1,是障碍,那这个位置的dp表,也只能填充0了
  • 其余的想法,与I没有任何差别
  • 还想多说一句就是,关于动态规划的题目,比如这道题,就是在动态规划标签下的题目,确实是存在套路的,无非就是你把它的推导过程找到,那这道题基本就解决了,当你先做I的时候,假如你解决了,遇到II,思路想法,不会差太多,只是给你多增加了一点别的限制,想想怎么改代码,把这种限制解决,那就又是一道问题的提交通过

少废话,上代码:

class Solution:
    def uniquePathsWithObstacles(self, grid):
        # 因为下面初始化的dp table 默认开始全是1
        # 但是这里有一个特殊情况,就是最开始你所在的位置就是障碍
        # 那自然返回0
        if grid[0][0] == 1:
            return 0

        row, column = len(grid), len(grid[0])
        # 开始初始化dp数组,行和列先定义一个初值1,后边在更新
        # 1 代表有一条不同的路径
        dp = [[1 for i in range(column)] for j in range(row)]

        # 开始填充第一行
        for i in range(1, column):
            # 如果给定数组中是1,代表有障碍
            # 就将dp table 相应位置填充为0
            # 代表没有路径可以走
            if grid[0][i] == 1:
                dp[0][i] = 0
            # 其余情况就是给定数组为0的情况,因为最开始都默认为1了
            # 所以此处不动dp table数值即可
            # 但是不动的条件,不只是给定数组为0的时候
            # 还必须是dp表前一个位置也是有路可走的,即为1
            elif grid[0][i] == 0 and dp[0][i - 1] == 1:
                pass
            # 如果上面都不满足,那就说明此时给定数组位置为0
            # 但是dp table 的前一个位置为0,说明是有障碍的
            # 此时不可能走得通
            # 所以要赋值为0,代表走不通
            else:
                dp[0][i] = 0
        # 开始填充第一列
        # 与行的思路是相同的
        for i in range(1, row):
            if grid[i][0] == 1:
                dp[i][0] = 0
            elif grid[i][0] == 0 and dp[i - 1][0] == 1:
                pass
            else:
                dp[i][0] = 0
        # 只要前面行列填充的正确,下面不会出什么大问题
        # 前期准备工作已做好,开始向下填充dp table
        for i in range(1, row):
            for j in range(1, column):
                # 无非多了一个判断,当给定数组位置为1,障碍时
                # dp table 直接赋值为0
                if grid[i][j] == 1:
                    dp[i][j] = 0
                # 其余正常情况,就按照I的公式即可
                else:
                    dp[i][j] = dp[i][j - 1] + dp[i - 1][j]

        return dp[-1][-1]  # 最后还是dp table 的最后一个元素,即为答案

运行时间和内存占用:

  • Runtime: 40 ms, faster than 91.23% of Python3 online submissions for Unique Paths II.
  • Memory Usage: 13.8 MB, less than 8.89% of Python3 online submissions for Unique Paths II.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值