二话不说,leetcode HOT100先开干,加油冲冲冲!这次开撕的是--爬楼梯。难度:简单
题目:假设你正在爬楼梯。需要 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:动态规划,将原来的递归方式换成基于数组存储:
var climbStairs = function(n) {
const dp = [1,1,2] // 定义数组用于缓存每次计算的值
for(let i = 3; i <= n; i++){
dp[i] = dp[i-1] + dp[i-2] // 斐波那契数列规律得出,将每次结果都存入数组
}
return dp[n] // 返回结果
}; // 时间复杂度O(n)
答案2:进一步优化,最优解,使用变量替换数组:
var climbStairs = function(n) {
// 定义prev保存上一次的值,cur保存当前值,res保存最后的结果
// 初始值都设置为1,保证n=0,n=1时,返回的结果也为1
let prev = 1,cur = 1,res = 1;
for(let i = 2; i <= n; i++){ //循环从第二阶开始,i<=n是因为n阶的时候也需要计算一次
// 每次新循环递进,cur就可以理解为成了n-1的值,prev可以理解为n-2的值
res = prev + cur // 临时存储最新的前两次值的和
prev = cur // 原来的cur变成了上一次的值,即赋值给prev
cur = res // 把res赋值给cur
}
return cur // 返回当前值
}; // 时间复杂度O(n)
若需要再简化一下赋值操作,可以使用ES6数组解构写法:
var climbStairs = function(n) {
let prev = 1,cur = 1;
for(let i = 2; i <= n; i++){
[cur,prev] = [prev + cur,cur]
}
return cur
}; // 时间复杂度O(n)