动态规划:力扣63. 不同路径 II

1、题目描述:
在这里插入图片描述
在这里插入图片描述
2、题解:
动态规划,
此题输入填表格的动态规划,与力扣62. 不同路径思路差不多。只不过多了障碍物,也就是障碍物的时候dp设置为0。
定义状态:
dp[i][j]为起始点到(i,j)处的路径数
状态转移方程:
机器人只能向左或者向下,dp[i][j] = dp[i-1][j] + dp[i][j-1]。但是遇到障碍物不更新
算法:

1、如果网格为空,则不存在路径,返回0
如果第一个格点或者结束位置有障碍物,那么机器人不能做任何移动或到达不了结束位置,我们返回结果 0。
定义状态数组dp[m][n],令所有网格初始化为0
否则 ,我们初始化dp[0][0]1 然后继续算法。
2、遍历第一列,如果[i,0]没有障碍物,设这个值是前一个节点的值dp[i,0] = dp[i-1,0]。
(其效果是,如果该位置有障碍物,则该位置的下面的位置都到不了)
3、遍历第一行,如果[0,j]没有障碍物,设这个值是前一个节点的值 dp[0,j] = dp[0,j-1]。
(其效果是,如果该位置有障碍物,则该位置的右面的位置都到不了)
4、从 obstacleGrid[1,1] 开始遍历整个数组,如果这个点有障碍物,设值为 0 ,这可以
保证不会对后面的路径产生贡献。如果某个格点初始不包含任何障碍物,就把值赋为上方和左侧两个格点
方案数之和 dp[i,j] = dp[i-1,j] + dp[i,j-1]
class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        #动态规划
        if len(obstacleGrid) == 0 or len(obstacleGrid[0]) == 0:
            return 0
        if obstacleGrid[0][0] == 1 or obstacleGrid[-1][-1] == 1:
            return 0
        m ,n = len(obstacleGrid),len(obstacleGrid[0])
        dp = [[0] * n for _ in range(m)] 
        dp[0][0] = 1
        # 第一列        
        for i in range(1,m):
            if obstacleGrid[i][0] == 0:
                dp[i][0] = dp[i - 1][0]
        # 第一行
        for j in range(1,n):
            if obstacleGrid[0][j] == 0:
                dp[0][j] = dp[0][j - 1]         
        for i in range(1,m):
            for j in range(1,n):
                if obstacleGrid[i][j] == 1:
                    dp[i][j] = 0
                else:
                    dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[-1][-1]

时间和空间复杂度都是O(M*N),空间可以继续优化O(1)。我们在所给的obstacleGrid数组上修改就行,思路和上面差不多,代码如下:

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        # 动态规划,不通过
        if len(obstacleGrid) == 0 or len(obstacleGrid[0]) == 0:
            return 0
        if obstacleGrid[0][0] == 1 or obstacleGrid[-1][-1] == 1:
            return 0
        m, n = len(obstacleGrid), len(obstacleGrid[0])
        obstacleGrid[0][0] = 1
        # 第一列
        for i in range(1, m):
            if obstacleGrid[i][0] == 0:
                obstacleGrid[i][0] = obstacleGrid[i - 1][0]
            else:
                obstacleGrid[i][0] = 0
        # 第一行
        for j in range(1, n):
            if obstacleGrid[0][j] == 0:
                obstacleGrid[0][j] = obstacleGrid[0][j - 1]
            else:
                obstacleGrid[0][j] = 0
        for i in range(1, m):
            for j in range(1, n):
                if obstacleGrid[i][j] == 1:
                    obstacleGrid[i][j] = 0
                else:
                    obstacleGrid[i][j] = obstacleGrid[i - 1][j] + obstacleGrid[i][j - 1]
        return obstacleGrid[-1][-1]

可对比下面的题:
动态规划:力扣62. 不同路径
动态规划:力扣64. 最小路径和

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值