[面试] 手写题-爬楼梯,斐波那契数列
爬楼梯
leetcode70. 爬楼梯
递归
时间复杂度 O(2^n)
var climbStairs = function(N) {if (N === 0) return 1;if (N === 1) return 1;return climbStairs (N - 1) + climbStairs (N - 2);
}
动态规划
时间复杂度:O(n)
本问题其实常规解法可以分成多个子问题,爬第n阶楼梯的方法数量,等于 2 部分之和
爬上 n−1
阶楼梯的方法数量。因为再爬1
阶就能到第n
阶
爬上 n−2
阶楼梯的方法数量,因为再爬2
阶就能到第n
阶
所以我们得到公式 dp[n]=dp[n−1]+dp[n−2]
同时需要初始化 dp[0]=1
和 dp[1]=1
var climbStairs = function(n) {let dp = [1,1];for(let i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];
};
压缩空间,优化
dp[i] 只与过去的两项:dp[i-1] 和 dp[i-2] 有关,没有必要存下所有计算过的 dp 项。用两个变量去存这两个过去的状态就好。
const climbStairs = (n) => {let prev = 1;let cur = 1;for (let i = 2; i <= n; i++) {const temp = cur; // 暂存上一次的curcur = prev + cur; // 当前的cur = 上上次cur + 上一次curprev = temp; // prev 更新为 上一次的cur}return cur;
}
斐波那契数列
leetcode 509
递归
var fib = function(N) {if (N === 0) return 0;if (N === 1) return 1;return fib(N - 1) + fib(N - 2);
}
动态规划
var fib = function(N) {let dp = [0,1];for(let i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];
}
爬楼梯问题: f(0)=1 , f(1)=1
。
斐波那契数列问题:f(0)=0 , f(1)=1
。
只是初始值不同, 都是f(n)=f(n−1)+f(n−2)
参考:
leetcode70-题解1
leetcode70-题解2