• 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
    
  • 相关阅读:
    前端程序员容易忽视的一些基础知识
    一道前端学习题
    Unity调用Windows对话框保存时另存为弹框
    Unity镜子效果的实现(无需镜子Shader)
    Unity射线检测的用法总结
    unity中实现简单对象池,附教程原理
    Unity调用Window提示框Yes/No(英文提示窗)
    Unity调用Windows弹框、提示框(确认与否,中文)
    C#LinQ语法
    服务器的购买与网站的创建
  • 原文地址:https://www.cnblogs.com/liaohuiqiang/p/9770759.html
Copyright © 2020-2023  润新知