前端算法(49)

73 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目

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

输入: n = 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 12. 1 阶 + 23. 2 阶 + 1

题目解析

思路一

总台阶数为一个台阶,只有一种方法;总台阶数为2个台阶,有两种方法(1步1台阶、1步1台阶;一步2台阶),后面的爬楼梯总数,就是在前面的基础上进行累加,dp方程可计为:dp[n] = dp[n-1] + dp[n-2],你可以理解为n从3开始,至于dp方程为什么是这样的。简单说就是,当前这一步台阶可以是从前面一步跨来,也可以是从前两步跨来的。不多解释了吧,就跟1+1=2一样,背住就行,爬楼梯就是这个解法,放弃了dp[0],避免了索引错位问题,1和2已经有结果了,当然从3开始,放弃了dp[0],所以dp[n]才是最终结果,遍历不能丢掉n

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function(n) {
    var dp = [];
    dp[1] = 1;dp[2] = 2;
    for(var i = 3; i<= n; i++){
        dp[i] = dp[i-1] + dp[i-2]
    }
    return dp[n]
};

思路二

我们通过将前10项列出来可以发现规律:

  • 1:1
  • 2:2 [上一项+1]
  • 3:3 [上一项+1]
  • 4:5 [上一项+2]
  • 5:8 [上一项+3]
  • 6:13[上一项+5]
  • 7:21[上一项+8]
  • 8:34[上一项+13]
  • 9:55 [上一项+21]
  • 10:89[上一项+34]

因此可以看出[1,1,2,3,5,8,13,21,34]这么个数列,正好就是斐波那契数列,那么我们就可以先设置一个数组 arr = [0,1],然后每次遍历加数组的最后一项再将数组最后两项相加最后再推入到数组尾部形成新的数组和新的结果

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function(n) {
    let arr = [0,1]
    let result = 1
    if(n === 1) return result
    for(let i = 0;i < n-1; i++) {
        let len = arr.length
        let count = arr[len - 1] + arr[len - 2]
        result += arr[len - 1]
        arr.push(count)
    }
    return result
};