题目链接:70. 爬楼梯
题目描述
假设你正在爬楼梯。需要 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
文章讲解:代码随想录
视频讲解:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题解1:动态规划
思路:1个台阶有1种走法,2个台阶有2种走法(1+1和2)。3个台阶可以看成在1个台阶的走法上再走2步,或者在2个台阶的走法上再走1步;4个台阶可以看成在3个台阶的走法上再走2步,或者在2个台阶的走法上再走1步。即 n 个台阶的走法可以看成在 n - 2个台阶的走法上再走2步,或者在 n - 1个台阶的走法上再走1步。因此可以用动态规划求解。
动态规划分析:
- dp 数组以及下标的含义:dp[i] 为 i 个台阶的走法。
- 递推公式:dp[i] = dp[i - 1] + dp[i - 2]。
- dp 数组初始化:dp[0] 没有意义,dp[1] = 1,dp[2] = 2。
- 遍历顺序:从前向后。
- 打印 dp 数组:1、2、3、5、......
javascript
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
const dp = new Array(n + 1);
dp[1] = 1; // 1个台阶有1种走法
dp[2] = 2; // 2个台阶有2种走法
for (let i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]; // i 个台阶有 dp[i - 1] + dp[i - 2] 种走法
}
return dp[n];
};
分析:时间复杂度为 O(n),空间复杂度为 O(n)。
题解2:动态规划优化
思路:i 个台阶的走法依赖于 i - 1 和 i - 2 个台阶的走法,可以用两个变量存储,在循环中更新这2个变量。
javascript
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
if (n <= 2) {
return n; // 1个台阶有1种走法,2个台阶有2种走法
}
let a = 1, b = 2; // a 为 i - 2个台阶的走法,b 为 i - 1 个台阶的走法
for (let i = 3; i <= n; i++) {
const c = a + b; // i 个台阶有 dp[i - 1] + dp[i - 2] 种走法
a = b; // 更新 a
b= c; // 更新 b
}
return b; // b 即为最终答案
};
分析:时间复杂度为 O(n),空间复杂度为 O(1)。
收获
当一个问题的答案依赖于较小的问题的答案时,可以使用动态规划法来求解。练习使用动态规划法解决问题,按照5部曲来分析。本题实际上是一个斐波那契数列。