leetcode 62.不同路径

文章介绍了如何使用动态规划和状态压缩的方法解决机器人在mxn网格中找到从左上角到右下角不同路径数量的问题。两种解法分别具有O(m*n)和O(n)的空间复杂度优化。
摘要由CSDN通过智能技术生成

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

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

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

示例
输入:m = 3, n = 7
输出:28

题解1
运用动态规划,因为有最优子结构所以可以用动态规划,我们令 dp[i][j] 是到达 i, j 最多路径。
列出状态转移方程:dp[i][j] = dp[i-1][j] + dp[i][j-1],
注意列出状态转移方程后再考虑边界条件,对于第一行 dp[0][j],或者第一列 dp[i][0],由于都是在边界,所以只能为 1。

时间复杂度:O(m*n)O(m∗n)
空间复杂度:O(m * n)O(m∗n)

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        #[]+[]相当于把"]["用逗号代替,把两个list连接变成一个list,即最外面的[]还是在的
        dp = [[1]*n] + [[1]+[0]*(n-1) for _ in range(m-1)]
        for i in range(1,m):
            for j in range(1,n):
                dp[i][j] = dp[i-1][j]+dp[i][j-1]
        return dp[-1][-1]

题解2:对题解1空间复杂度的优化,也叫做状态压缩:因为我们每次只需要 dp[i-1][j],dp[i][j-1],所以我们只要记录这两个数,直接看代码吧!

优化1(空间复杂度 O(2n)):令m为行、n为列,行列两层循环中的循环体cur[j] = pre[j] + cur[j-1] ,cur[j] 表示遍历到的从起点到第i行第j列的路径数,它等于当前第i行第j-1列即 cur[j-1]的值 加上 上一行第j列的值pre[j] 内层循环一次后即计算完了第i行各列的值,在计算下一行第i+1行之前执行pre = cur.clone(); 即第i行的值就是第i+1行的前一行,两层循环完以后最后要到达的终点的行的值存于pre数组中,所以取出 pre[n-1]即可

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


优化2(空间复杂度 O(n)):令m为行、n为列,相比优化1,少了pre数组,cur[j] += cur[j-1] 即 cur[j] = cur[j-1] + cur[j] 未赋值之前右边的cur[j] 始终表示当前行第i行的上一行第j列的值,赋值之后左边的cur[j]表示当前行第i行第j列的值,cur[j-1] 表示当前行第i行第j-1列的值(cur[j-1] 在计算cur[j]之前就已经计算了,所以表示的是当前行而不是上一行 ), 思路跟优化1是一样的,除了少用了一个数组

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值