(No.3)前端写算法之--爬楼梯

79 阅读2分钟

二话不说,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)