爬楼梯算法
现在只看明白动态规划,也没有很难哟!!
题目
70. 爬楼梯假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
java题解
class Solution {public int climbStairs(int n) {int p = 0, q = 0, r = 1;for (int i = 1; i <= n; ++i) {p = q; q = r; r = p + q;}return r;}
}
这个爬楼梯算法实际上是一个经典的动态规划问题,也可以看作是斐波那契数列的变种。让我来详细解释一下:
问题理解
假设你正在爬楼梯,需要n
阶才能到达楼顶。每次你可以爬 1 或 2 个台阶。问有多少种不同的方法可以爬到楼顶?
例如:
- 当
n=2
时,有两种方法:1+1 或直接 2 步 - 当
n=3
时,有三种方法:1+1+1、1+2、2+1 - 当
n=4
时,有五种方法:1+1+1+1、1+1+2、1+2+1、2+1+1、2+2
动态规划思路
动态规划的核心是将大问题分解为小问题,并存储小问题的解避免重复计算。
对于爬楼梯问题,关键观察点是:
- 到达第
i
阶楼梯的方法数 = 到达第i-1
阶的方法数(再爬 1 步) + 到达第i-2
阶的方法数(再爬 2 步) - 即状态转移方程:
dp[i] = dp[i-1] + dp[i-2]
代码解释
你提供的代码正是基于这个思路实现的,只不过使用了滚动数组优化空间复杂度:
java
public int climbStairs(int n) {int p = 0, q = 0, r = 1;for (int i = 1; i <= n; ++i) {p = q; // p 记录 dp[i-2] 的值q = r; // q 记录 dp[i-1] 的值r = p + q; // r 计算当前 dp[i] = dp[i-1] + dp[i-2]}return r;
}
执行过程示例
以n=3
为例:
- 初始状态:
p=0
,q=0
,r=1
- 循环开始:
i=1
:p=0
,q=1
,r=p+q=1
→ 到达第 1 阶有 1 种方法i=2
:p=1
,q=1
,r=p+q=2
→ 到达第 2 阶有 2 种方法i=3
:p=1
,q=2
,r=p+q=3
→ 到达第 3 阶有 3 种方法
- 返回结果:
r=3
复杂度分析
- 时间复杂度:O (n),只需遍历一次
- 空间复杂度:O (1),只使用了三个变量
这种优化方法避免了创建长度为n
的数组,在空间效率上更高。本质上,这个问题和斐波那契数列的计算是一样的,只是起始条件略有不同(斐波那契通常从 0 和 1 开始,而爬楼梯这里从 1 和 1 开始)。