1 问题描述
假设有 n n n阶楼梯,每次可以爬1或2阶,求有多少种爬楼梯的方式,使得我们可以登顶。
在动态规划那一节中有给出在上面条件下加一个“不能连续两次爬2阶”时的解法。
2 排列组合法
自己实现的时候用的方法比较low,将这个问题分解成求 n n n可以分成多少个1与多少个2的组合,假设2的数目有 m m m个,那么1的数目有 n − 2 m n-2m n−2m个,一共需要走 n − m n-m n−m步,这里面的走法就有 C n − m m C_{n-m}^{m} Cn−mm种,遍历所有可能的 m m m的数目,得到最终解:
class Solution:
def climbStairs(self, n: int) -> int:
if n == 1:
return 1
else:
numtwo = n // 2 # 统计n中可以由多少个2组成
numway = 1
predot = 1
for i in range(1, numtwo + 1): # 采取的方案中,n的数目从0到numtwo
predot = predot * i
numway += (self.stepdot(n, i) / predot)
return int(numway)
def stepdot(self, n, m):
a = n - 2 * m + 1
b = n - m
if a == b:
return a
else:
sd = 1
for j in range(a, b + 1):
sd = sd * j
return sd
时间复杂度为 O ( n 2 ) O(n^2) O(n2),比较低效的一种解法。
3 动态规划法
感觉做这种题目还是应该去学习动态规划的思想,而不是老是选择可以暴力求解的方法,多看一些解法自己也能够收获成长。
假设一共还是有 n n n阶楼梯,我们把走法数量记为 f ( n ) f(n) f(n),从 n − 1 n-1 n−1阶或 n − 2 n-2 n−2都可以一步登上第 n n n阶,因此:
f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n)=f(n-1)+f(n-2)