leetcode专题训练 62. Unique Paths

本文深入探讨了机器人从起点到终点的路径规划算法,包括深度优先搜索(DFS)、动态规划和排列组合三种方法。DFS方法虽然直观但效率低下,动态规划方法通过状态转移方程优化了计算过程,而排列组合法则提供了数学上的简洁解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.最开始用的dfs遍历的方法,应该能算出正确答案,但是超时了。思考了一下时间复杂度,这个dfs方法的复杂度应该是(m+n−1)Cm+n−2m−1(m+n-1)C_{m+n-2}^{m-1}(m+n1)Cm+n2m1,超时的样例是m=23,n=12,我计算了一下复杂度的具体数值,为262662462526464000,肯定会超时,所以最好能用其他方法,就不要暴力搜索了。
(需要注意leetcode的输入是许多案例同时输入,所以在定义并调用需要修改的类变量之前,一定要对类变量进行初始化,不然类变量会保持上一次输入后的状态)

class Solution:
    count = 0
    dirs = [[0, 1], [1, 0]]

    def dfs(self, m: int, n: int, r: int, c: int):
        if r == m-1 and c == n-1:
            Solution.count += 1
            return
        for Dir in Solution.dirs:
            tmpr = r + Dir[0]
            tmpc = c + Dir[1]
            if tmpr >= m or tmpc >= n:
                continue
            self.dfs(m, n, tmpr, tmpc)
        return

    def uniquePaths(self, m: int, n: int) -> int:
        Solution.count = 0
        self.dfs(m, n, 0, 0)
        return Solution.count

2.第二种方法尝试的是动态规划的方法。因为到每个格子的步数是一定的,所以可以将该步数当作阶段变量考虑,到k步格子的路径条数,仅与到k-1步格子的路径条数相关,更加精确的说,仅与到k步格子的左或上相邻格子(均为k-1步格子)的路径相关,所以可以用动态规划的思想求解。其实我原来想过用动态规划的方法,不过觉得dfs思路简单就想暴力搞一发试试,然后果然超时了。所以还是该用动态规划就用动态规划吧。
dp[i][j]dp[i][j]dp[i][j]代表到第i行第j格总共有多少路径。
状态转移方程:

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

完整代码:

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
     	# 直接全部初始化为1,减少了单独初始化第一行和第一列的过程
     	# 需要注意dp[0][0]也为1
        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]
        return dp[m-1][n-1]

3.第三种方法是排列组合的方法
从初始点(0,0)到目标点(m-1, n-1)的路径中,总共需要经过(m+n-2)步,其中(m-1)步向下,(n-1)步向右。此时的问题就转化为了,在这(m+n-2)步中,第多少步向下,第多少步向右。用排列组合的惯用黑白球说法来说,就是(m-1)个黑球和(n-1)个白球的排列组合问题。问题转化后,求解就很简单了,用公式Cm+n−2m−1C_{m+n-2}^{m-1}Cm+n2m1即可求解。

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        return int(math.factorial(m+n-2)/math.factorial(m-1)/math.factorial(n-1))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值