问题描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
题目链接:LeetCode.70 爬楼梯
题目分析
此题为一道典型的递归算法入门题目,结合递归算法需要满足的两个基本条件1.问题简化后的形式与原形式相同,2.有简洁的递归终止条件对该问题进行分析:
-
问题简化后的形式
假设当前还需要爬x阶楼梯才能到达楼顶,那么接下来的可选路段只有两种可能,即爬两阶或爬一阶的问题。因此,该问题可以被拆解为 p ( x ) = p ( x − 1 ) + p ( x − 2 ) p(x) = p(x-1) + p(x-2) p(x)=p(x−1)+p(x−2)以此类推,可以将一个较大的问题拆分为两个子问题,并进行循环嵌套分解。即满足问题简化后的形式与原问题相同这一递归基本条件。 -
有简洁的递归终止条件
当所剩楼梯为1阶时,下一步的可选方式只有一种,即爬一阶,则对应的表达式为 p ( 1 ) = 1 p(1) = 1 p(1)=1;
当所剩楼梯为2阶时,下一步的可选方式只存在两种,即爬两阶以及爬一阶,则对应的表达式为 p ( 2 ) = 2 p(2) = 2 p(2)=2
综上所述,该问题的递归终止条件即为 x = 1 x=1 x=1或 x = 2 x=2 x=2。
代码实现
使用python语言直接递归实现该问题的代码如下:
class Solution:
def climbStairs(self, n: int) -> int:
if n == 1:
return 1
elif n == 2:
return 2
else:
return self.climbStairs(self, n-1) + self.climbStairs(self, n-2)
算法优化
虽然上述的代码能够在较小的参数条件下解决该问题,但在计算过程中,每次都需要对n进行递归计算,这就导致当参数较大时该算法会占用更大的堆栈资源,耗费更多的时间。对此,需要对该算法进行一定程度的优化。
优化思想
对此,可以考虑引入一个参数列表,来存储每次计算得到的n值,当后续递归中需要请求已有的参数值时,只需要通过查表,就能够得到对应结果,从而降低迭代次数,减少时间消耗。
优化后的代码实现如下:
class Solution:
def climbStairs(self, n: int) -> int:
mem = [-1 for i in range(n+1)]
def dfs(n, mem):
if n == 1:
return 1
elif n == 2:
return 2
if mem[n] == -1:
mem[n] = dfs(n-1, mem) + dfs(n-2, mem)
return mem[n]
return dfs(n, mem)`