这是一个典型的斐波那契数列
上第N个台阶的方法是,上N-1个台阶以及N-2个台阶的和,这里应该好理解
f(n) = f(n-1) + f(n-2)
f(1) = 1
f(2) = 2
上面的方程我们就可以理解为状态转移方程
这样就可以得到代码
递归
var climbStairs = function (n) {
if (n <= 3) return n;
return climbStairs(n - 1) + climbStairs(n - 2);
};
很不幸,这种方法可以解答,但是会超时。因为在递归的过程中,有大量的重复计算,这里属实没必要
DP
这里利用数组来存放到n级台阶的不同组合,返回数组末尾即可
var climbStairs = function (n) {
if (n <= 3) return n;
let dp = [0, 1, 2, 3];
for (let i = 4; i <= n; ++i) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
};
节约存储空间
对比dp的方法,这里可以节约存储空间
var climbStairs = function (n) {
if (n <= 3) return n;
let first = 1;
let second = 2;
for (let i = 3; i <= n; ++i) {
let tmp = second;
second += first;
first = tmp;
}
return second
};
| 方法 | 时间复杂度 | 空间复杂度 | 是否推荐 |
|---|---|---|---|
| 递归 | O(2ⁿ) | O(n) | ❌(超时) |
| 动态规划 | O(n) | O(n) | ✅ |
| 状态压缩 | O(n) | O(1) | ✅✅✅ 最推荐 |