目录
力扣第70题

爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

算法思想
基本情况
javascript
dp[0] = 1; // 0个台阶 - 1种方法(什么都不做)
dp[1] = 1; // 1个台阶 - 1种方法(只能爬1步)
动态规划递推关系
javascript
for(let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
核心思想
- 要到达第 i 级台阶,可以:
从第 i-1 级爬 1 步 上来(有 dp[i-1] 种方法)【爬上 n−1 阶楼梯的方法数量。因为再爬1阶就能到第n阶】
从第 i-2 级爬 2 步 上来(有 dp[i-2] 种方法)【爬上 n−2 阶楼梯的方法数量,因为再爬2阶就能到第n阶】
- 因此:dp[i] = dp[i-1] + dp[i-2]
可以换种角度理解
只考虑最后一步,假设有4个台阶,最后一步有两种走法(剩下一个台阶的可能性组合和剩下两个台阶可能性组合)。两种走法的所有可能性都想家就是所有的可能性。
举例:
- 1+1+1+1 剩下一个台阶
- 1+2+1 剩下一个台阶
- 2+1+1 剩下一个台阶
- 1+1+2 剩下两个台阶
- 2+2 剩下两个台阶
根据列出的规律可以发现剩下一个台阶的走法是(4-1)个台阶走法的总和;剩下两个台阶的走法(4-2)个台阶的走法的总和。因此可以得出结论假设有n个台阶那总的走法总数等于(n-1)个台阶走法数和(n-2)个台阶走法数的相加
即 dp[n]=dp[n−1]+dp[n−2]
时间复杂度与空间复杂度
-
时间复杂度:O(n) - 只需遍历一次
-
空间复杂度:O(n) - 需要长度为 n+1 的数组
code
javascript
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
const dp = [];
dp[0] = 1;
dp[1] = 1;
for(let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
};