• 62. Unique Paths


    问题

    有一个m x n的格子,从左上角走到右下角,每次只能向右或向下,问有多少种走法

    思路

    dp解法
    当你处在某个格子coordinate(i,j),只可能从上方来,或者从左方来,那么把你“左上角到你左方格子”有多少种走法,加上“左上角到你上方格子”有多少种走法,就是“到这个coordinate(i,j)格子”有多少种走法。

    [dp[i][j] = dp[i-1][j] + dp[i][j+1] ]

    dp矩阵初始化为1,因为对于最上面一行和最左边一列,只有一种走法。

    dp矩阵可以优化成数组,这里不多解释了,和之前 486. Predict the Winner 给出的三个gif图是一样的道理。

    时间复杂度O(n*m)
    空间复杂度O(n)或O(m),可以自己取小的那个O

    排列组合的解法
    考虑一个3行7列的格子,一定会走(3-1)+(7-1)也就是8步,减一是因为起点和终点不需要走。

    那么在这8步里面,我们只考虑哪一步向下走,是有(3-1)种选择,也就是两种选择,这样组合出来的就是(C^2_8)

    或者在这8步里面,我们只考虑哪一步向右走,有(7-1)种选择,组合出来就是(C^6_8),跟(C^2_8)是等价的。

    因为8步里面要么向右走,要么向下走。我们只需要纯粹考虑两种。比如只考虑向下走有哪两步,剩下六步都是向右走。比如只考虑向右走有哪6步,剩下两步都会向下走。

    所以我们计算(C^{min(n-1, m-1)}_{n+m-2})即可。这里给一下排列组合的公式,(C^m_n = frac{n!}{m! (n-m)!}, A^m_n = frac{n!}{(n-m)!})

    时间复杂度O(min(n, m)),空间复杂度O(1)

    代码

    dp解法

    class Solution(object):
        def uniquePaths(self, m, n):
            """
            :type m: int
            :type n: int
            :rtype: int
            """
            dp = [1 for _ in range(n)]
            for i in range(1,m):
                for j in range(1,n):
                    dp[j] = dp[j] + dp[j-1]
            return dp[n-1]  
    

    排列组合的解法

    class Solution(object):
        def uniquePaths(self, m, n):
            """
            :type m: int
            :type n: int
            :rtype: int
            """
            n, m = n+m-2, min(n-1, m-1)
            numerator = denominator = 1
            for i in range(m):
                numerator *= n-i
                denominator *= i+1
            return numerator / denominator
    
  • 相关阅读:
    动态添加删除控件
    文件下载源码
    poj 1300 欧拉回路、通路 解题报告
    hdu 1232 并查集 或者 深搜
    hdu 2546 01背包问题
    强连通图的判断 hdu 1269
    hdu 2159 二维费用背包问题
    Hdu 3336 kmp+dp解题报告
    hdu 3639 强连通练习使用
    hdu 1712 分组背包问题
  • 原文地址:https://www.cnblogs.com/liaohuiqiang/p/9770759.html
Copyright © 2020-2023  润新知