思路来自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,通往该节台阶只有两种方法:
- 在第 ( i − 1 ) (i-1) (i−1) 节后向上爬1阶
- 在第 ( i − 2 ) (i-2) (i−2) 节后向上爬 2 阶。
所以到达第 i i i节的方法总数就是到第 i − 1 i-1 i−1节和第 ( i − 2 ) (i-2) (i−2) 节的方法数之和。
令 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[i−1]+dp[i−2]
代码
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=∣∣∣∣FnFn−1Fn−1Fn−2∣∣∣∣
则
Q n + 1 = Q n ⋅ ∣ 1 1 1 0 ∣ Q_{n+1}=Q_{n}\cdot \begin{vmatrix} 1 & 1\\ 1 & 0 \end{vmatrix} Q