算法题解:爬楼梯
问题描述
假设你正在爬楼梯,需要爬 n 阶才能到达楼顶。每次你可以爬 1 或 2 个台阶。问有多少种不同的方法可以爬到楼顶?
示例
示例 1:
输入:n = 2
输出:2
解释:
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入:n = 3
输出:3
解释:
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
提示
1 <= n <= 45
解题思路
方法一:动态规划(推荐)
核心思想:这是一个典型的动态规划问题。到达第 n 阶楼梯的方法数等于到达第 n-1 阶和第 n-2 阶方法数之和,因为最后一步可以是爬 1 阶或 2 阶。
状态转移方程:
dp[n] = dp[n-1] + dp[n-2]
边界条件:
- dp[0] = 1(地面,视为一种方法)
- dp[1] = 1
优化:实际上只需要维护前两个状态,可以将空间复杂度优化到 O(1)
复杂度分析:
- 时间复杂度:O(n)
- 空间复杂度:O(1)
方法二:矩阵快速幂(数学方法)
利用矩阵快速幂可以将时间复杂度优化到 O(log n),但实现较复杂,对于 n ≤ 45 的约束,方法一已经足够高效。
方法三:递归(不推荐)
直接递归实现会导致大量重复计算,时间复杂度为 O(2^n),在 n 较大时效率极低。
代码实现
动态规划实现(空间优化版)
class Solution:
def climbStairs(self, n: int) -> int:
if n == 1:
return 1
a, b = 1, 2
for _ in range(2, n):
a, b = b, a + b
return b
完整动态规划实现
class Solution:
def climbStairs(self, n: int) -> int:
if n == 1:
return 1
dp = [0] * (n + 1)
dp[0], dp[1] = 1, 1
for i in range(2, n + 1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
代码解释
-
空间优化版:
- 初始化前两个台阶的方法数 a=1(1阶),b=2(2阶)
- 从第3阶开始迭代计算,每次更新 a 和 b 的值
- 最终返回 b 的值
-
完整动态规划版:
- 创建 dp 数组存储各阶方法数
- 初始化 dp[0] 和 dp[1]
- 通过循环计算每阶的方法数
- 返回 dp[n]
示例分析
以 n=3 为例:
-
空间优化版:
- 初始 a=1, b=2
- 第一次循环:a=2, b=1+2=3
- 返回 b=3
-
完整动态规划版:
- dp=[1,1,0,0]
- dp[2] = dp[1]+dp[0] = 1+1 = 2
- dp[3] = dp[2]+dp[1] = 2+1 = 3
- 返回 dp[3]=3
数学解释
这个问题实际上是斐波那契数列的变种:
- F(1) = 1
- F(2) = 2
- F(n) = F(n-1) + F(n-2) (n > 2)
总结
爬楼梯问题是动态规划的经典入门题目,展示了如何将问题分解为子问题并利用子问题的解来构建原问题的解。对于这类问题:
- 识别可以分解为相似子问题的问题结构
- 定义状态转移方程
- 确定边界条件
- 选择适当的空间优化方法
掌握这种动态规划的思路可以解决许多类似的计数问题,如果您对动态规划算法基础不了解可以看这篇博客:https://blog.csdn.net/lcgsmile/article/details/146914067
857

被折叠的 条评论
为什么被折叠?



