天天看点

leetcode(力扣) 62. 不同路径 & 63. 不同路径 II (动态规划)

文章目录

  • 62.不同路径:
  • 题目描述
  • 简化题目
  • 思路分析
  • 完整代码
  • 63.不同路径 II

62.不同路径:

题目描述

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1:

输入:m = 3, n = 7

输出:28

示例 2:

输入:m = 3, n = 2

输出:3

解释:

从左上角开始,总共有 3 条路径可以到达右下角。

  1. 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向下

示例 3:

输入:m = 7, n = 3

输出:28

示例 4:

输入:m = 3, n = 3

输出:6

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

简化题目

每次可以往右或者往下走一格,从左上走到右下一共有多少种路径。

leetcode(力扣) 62. 不同路径 & 63. 不同路径 II (动态规划)

思路分析

动规五步走:

1.确定dp数组含义:

dp[i][j] 表示 从左上角出发点到[i][j]格有多少种路径。

2.确定递推公式:

动态规划问题都有一种局部操作的思想,这道题就是看到[i][j]有几种路径由谁决定,由于题目已经说了,只能由往右边或者下边走,所以到[i][j] 的不同路径数,由dp[i-1][j]和dp[i][j-1]相加决定。

所以有递推公式:dp[i][j] = dp[i-1][j]+dp[i][j-1]

3.初始化dp数组:

由于只能往右或者往下走,所以他们的值都是1,也就是只有一种路径方法。

dp[0][i] 和dp[j][0]都是1.

4.确定遍历顺序:

从左到右一层一层遍历就行了。

5.模拟dp结果:

直接偷一张图。最终结果显然是dp[-1][-1]。

leetcode(力扣) 62. 不同路径 & 63. 不同路径 II (动态规划)

完整代码

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp =[[1 for i in range(n)]for j in range(m)]
        for i in range(1,m):
            for j in range(1,n):
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
        print(dp)
        return dp[-1][-1]      

63.不同路径 II

这道题根据上一道题改了一下,他在棋盘上加了障碍物。

还是从左上角到右下角,问你有几种路径方法,中间加了一块红色的障碍物。

leetcode(力扣) 62. 不同路径 & 63. 不同路径 II (动态规划)

与上一题不同的地方就是初始化有较大不同,其他位置基本没变。

可以想象一种情况,就是这个障碍物在最左边或者在最上边的情况。

比如

leetcode(力扣) 62. 不同路径 & 63. 不同路径 II (动态规划)

那么在dp数组里就是 1,1,1,1,0,0,0。

在上一题已经说过了,最左边和最上边所有的点都是只有一种走法,因为只能走右边或者下边。所以如果障碍物在最左边或者最上边的话,那么最左一条边或最上一条边的障碍物后面就都是0了,因为唯一的路径被切断了,没办法到达了。

一开始dp数组全部为0,只要障碍物不在起点,则就让dp[0][0] =1 依此来初始化dp[i][0]和dp[0][j]的值

这是和上一题初始化dp数组部分不太一样的地方。

另一个不一样的点就是在递推公式哪里,如果碰到障碍物,则不更新dp里的值,让dp数组对应障碍物的位置始终保持0,这样障碍物哪里的路径就一直是0了。

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        col  = len(obstacleGrid[0])
        row = len(obstacleGrid)

        dp = [[0 for i in range(col)] for j in range(row)]
        if obstacleGrid[0][0] == 1:
            return 0
        else:
            dp[0][0] =1  
        for j in range(1,col):
            if obstacleGrid[0][j]!=1:
                dp[0][j] = dp[0][j-1]
        for i in range(1,row):
            if obstacleGrid[i][0]!=1:
                dp[i][0] = dp[i-1][0]
        for i in range(1,row):
            for j in range(1,col):
                if obstacleGrid[i][j] !=1:
                    dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[-1][-1]