leetcode刷题随记2-爬楼梯

题目描述:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

我的第一想法是递归:

class Solution:
    def climbStairs(self, n: int) -> int:
        if n==1:
            return 1
        if n==2:
            return 2
        return self.climbStairs(n-1)+self.climbStairs(n-2)

但这样会超出时间限制,因为会重复计算相同的子问题,比如说计算n=5时,会先计算子问题n=4和n=3,再计算n=3、n=2(n=4的子问题)和n=2、n=1(n=3的子问题),这样就相当于n=3和n=2被重复计算了。如果我们能够把计算过的结果保存起来,这样就可以在需要用的时候直接取用,而不必重复计算了。

解法1:动态规划

动态规划(Dynamic Programming)是一种算法设计技术,它通常用于优化递归算法,避免重复计算相同子问题,从而提高算法的效率。

在动态规划中,问题被分解为更小的子问题,然后通过解决子问题来解决原始问题。与递归不同的是,动态规划将中间结果保存起来,避免重复计算,从而节省时间。

在爬楼梯问题中,每一步可以选择爬1个台阶或2个台阶,到达楼顶的方法数取决于到达前两个台阶和前一个台阶的方法数。动态规划通过填充一个数组(例如 dp 数组)来保存中间结果,从底向上计算并存储到达每个台阶的方法数。这样,每个子问题只需解决一次,而不是递归方法中的重复计算。

动态规划的“动态”体现在问题的阶段性划分和中间结果的保存,而“规划”则指的是在解决问题的阶段中进行的决策。在爬楼梯问题中,每一步决策是选择爬1个台阶或2个台阶,而中间结果则是保存在 dp 数组中。

总的来说,动态规划是通过划分问题、保存中间结果、递推求解的一种优化算法技术,它在很多问题中能够有效地提高算法的效率。

class Solution:
    def climbStairs(self, n: int) -> int:
        if n <= 2:
            return n

        dp = [0] * (n + 1) # 列表dp中的每项dp[n]保存到达第n阶台阶的方法数
        dp[1] = 1
        dp[2] = 2

        for i in range(3, n + 1):
            dp[i] = dp[i - 1] + dp[i - 2]

        return dp[n]

解法2:记忆化搜索

记忆化搜索是一种优化递归算法的技术,它通过缓存(记忆)先前计算的结果,以避免对相同的输入参数进行重复计算

class Solution:
    def climbStairs(self, n: int) -> int:
        memo = {}

        def helper(n):
            if n <= 2:
                return n
            if n not in memo:
                memo[n] = helper(n - 1) + helper(n - 2)
            return memo[n]

        return helper(n)

@cache 装饰器:这是一个装饰器,用于将下面的函数 dfs 转化为记忆化搜索的版本。它会自动缓存函数的输入参数和对应的输出结果,以避免对相同参数的重复计算。 

class Solution:
    def climbStairs(self, n: int) -> int:
        @cache
        def dfs(i:int)->int:
            if i<=1:
                return 1
            else:
                return dfs(i-1) +dfs(i-2)
        return dfs(n)

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值