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
posted @ 2018-10-11 09:53  PilgrimHui  阅读(278)  评论(0编辑  收藏  举报