台阶算法

265 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

题目描述


一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:2

示例 2:

输入:n = 7
输出:21

示例 3:

输入:n = 0
输出:1

提示:

  • 0 <= n <= 100

解法1 递归

由题目的规律f(0) = 1,f(1) = 1,f(2) = 2...f(7) = 21;

符合递归函数f(n) = f(n-1) + f(n-2);

/**
 * @param {number} n
 * @return {number}
 */
 var numWays = function(n) {
    if(n == 0 || n == 1){
        return 1;
    }
    return (numWays(n - 1) + numWays(n - 2)) % 1000000008;
};

虽然逻辑正确,但明显这种不行,超时了

image.png


解法2 解法1 优化

由解法1知:

f3 = f(2) + f(1);

f4 = f(3) + f(2);

f5 = f(4) + f(3);

f6 = f(5) + f(4);

则可以转成一维循环

再观察这种模式,f(2),f(3)重复了,所以我们可以设置一个对象存储历史值

f3 = f(2) + f(1);

f4 = f(3) + f(2);

f5 = f(4) + f(3);

f6 = f(5) + f(4);

var numWays = function(n) {
    let obj = {
        0: 1,
        1: 1
    }
    let mod = 1e9 + 7;
    for(var i = 2; i <= n; i++){
        obj[i] = obj[i - 1] + obj[i - 2];
        obj[i] = obj[i] % mod;
    }
    return obj[n];
};

image.png


解法3 动态规划

由解法2知,obj对象存储了大部分历史数据,是没有用的,我们只需返回最后一个值。

我们只需要不断的往后挪动,cur即可以记录当前的数据

image.png

js递归处理:

var numWays = function(n){

    if(n < 2){
        return 1;
    }

    let pre = 1,cur = 1,next;
    let mod = 1e9 + 7;
    for(var i = 1; i < n; i++){
        next = (cur + pre) % mod;
        pre = cur;
        cur = next;
    }

    return cur;
}

image.png