爬楼梯 python

本文介绍了爬楼梯问题的多种Python解决方案,包括暴力算法、优化的暴力算法(记忆化)、动态规划、斐波那契数列、Binet's方法、斐波那契公式和GF算法,详细阐述了每种方法的思路、代码实现及时间空间复杂度分析。

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

思路来自leetcode,但是全是python改写

题目描述

假设你正在爬楼梯,需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶,你有多少种不同的方法可以爬到楼顶呢?

解决方案

一、 暴力算法

将1台阶/步与2台阶/步的所有的情况进行遍历和组合
例如第1步走1个台阶,则第2步有两种选择,针对每种选择在后续的步中又有两种选择……像极了树形递归。
递归结束的判断条件事当前走过的总台阶数大于等于n,如果恰巧等于n,则返回1(代表该路可行),否则返回0;所有的返回值进行累加,即汇总可行的总方案数

代码

其中climb_Stairs(0) 中的0表示初始、还没迈出任何一步
递归的返回、回溯只是将可行的分支方案进行汇总

class Solution:
    def climbStairs(self, n: int) -> int:
        self.N=n
        def climb_Stairs(i):
            if i>self.N:return 0
            if i==self.N:return 1
            return climb_Stairs(i+1)+climb_Stairs(i+2)
        return climb_Stairs(0)
  • 时间复杂度O( n 2 n^{2} n2)
  • 空间复杂度O(n) 【因为递归的深度就是n】

二、优化的暴力算法(记忆化)

对上述方法进一步优化,可以将每次的结果进行存储,如果递归到某一分支的当前深度,可以直接查找曾经计算过的结果,不用并返回,不用频繁地重复往下递归和计算

代码

class Solution:
    def climbStairs(self, n: int) -> int:
        self.Hash={
   
   }
        self.N=n
        def climb_Stairs(i):
            if i>self.N:return 0
            if i==self.N:return 1
            if str(i) in self.Hash:return self.Hash[str(i)]
            self.Hash[str(i)]=climb_Stairs(i+1)+climb_Stairs(i+2)
            return self.Hash[str(i)]
        return climb_Stairs(0)
  • 时间复杂度O(n)
  • 空间复杂度O(n)

三、动态规划

对于任意一节台阶 i i i,通往该节台阶只有两种方法:

  1. 在第 ( i − 1 ) (i-1) (i1) 节后向上爬1阶
  2. 在第 ( i − 2 ) (i-2) (i2) 节后向上爬 2 阶。
    所以到达第 i i i节的方法总数就是到第 i − 1 i-1 i1节和第 ( i − 2 ) (i-2) (i2) 节的方法数之和。
    d p [ i ] dp[i] dp[i]表示能到达第 i i i 阶的方法总数:
    d p [ i ] = d p [ i − 1 ] + d p [ i − 2 ] dp[i]=dp[i−1]+dp[i−2] dp[i]=dp[i1]+dp[i2]

代码

class Solution:
    def climbStairs(self, n: int) -> int:
        if n==1:return 1
        dp=[1,2]
        for idx in range(3,n+1):dp.append(dp[-1]+dp[-2])
        return dp[-1]
  • 时间复杂度O(n)
  • 空间复杂度O(n)

四、斐波那契数

上书方法所产生的dp数组就是一个斐波那契数列(当前项等于前两项之和),那么斐波那契那一系列的方法都可以直接用,首先这个解决这个题目只需要得到斐波那契数列的最后一项,不需要存储每一项,因此可以降低空间复杂度,只实时地保存最后一项即可

代码

class Solution:
    def climbStairs(self, n: int) -> int:
        if n==1:return 1
        PerNum,LastNum=1,2
        for idx in range(3,n+1):
            Out,PerNum=PerNum+LastNum,LastNum
            LastNum=Out 
        return Out
  • 时间复杂度O(n)
  • 空间复杂度O(1)

五、Binets 方法(斐系)

这个leetcode上解释的很烂,兄弟们看我的:
F n F_{n} Fn为斐波那契数列的第n项,

Q n = ∣ F n F n − 1 F n − 1 F n − 2 ∣ Q_{n}= \begin{vmatrix} F_{n} & F_{n-1} \\ F_{n-1} & F_{n-2} \end{vmatrix} Qn=FnFn1Fn1Fn2

Q n + 1 = Q n ⋅ ∣ 1 1 1 0 ∣ Q_{n+1}=Q_{n}\cdot \begin{vmatrix} 1 & 1\\ 1 & 0 \end{vmatrix} Q

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值