文章目录
- [70. 爬楼梯](#70. 爬楼梯)
70. 爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例:
输入:n = 3
输出:3
Solution
我们先通过直观的方式思考问题:对于给定的阶梯数n,每次爬1阶或2阶,因此有两种选择,可以分解为以下子问题:
- 爬上n-1阶,再爬1阶
- 爬上n-2阶,再爬2阶
所以解就是上述两个子问题的和。
python
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)
上述直接递归的缺点在于重复计算,那么我们可以保存已经计算的子问题的结果。
python
class Solution:
def climbStairs(self, n: int) -> int:
memo = [0] * (n + 1)
return self.climb_with_memoization(n, memo)
def climb_with_memoization(self, n: int, memo: list) -> int:
if n == 1:
return 1
if n == 2:
return 2
if memo[n] > 0:
return memo[n]
memo[n] = self.climb_with_memoization(n - 1, memo) + self.climb_with_memoization(n - 2, memo)
return memo[n]
记忆化递归依然使用了递归结构,而递归结构可以转换为迭代结构。我们可以从底部开始计算,逐步构建解,直到达到n。
python
class Solution:
def climbStairs(self, n: int) -> int:
if n <= 2:
return n
dp = [0] * (n + 1)
dp[1], dp[2] = 1, 2
for i in range(3, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]
return dp[n]
观察上述代码,我们发现每次计算只使用了前两个状态的值。因此,完全没有必要保存所有的值,只需保存最后两个状态。
python
class Solution:
def climbStairs(self, n: int) -> int:
if n <= 2:
return n
a, b = 1, 2
for _ in range(3, n + 1):
a, b = b, a + b
return b