[剑指 Offer 10- II. 青蛙跳台阶问题]

115 阅读2分钟

「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

题目描述

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

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

思路解析

当青蛙处于0级台阶时,它只有一种跳法;当青蛙要跳上1级时,它也只有一种跳法‘当跳上2级时,他又两种方法。通过题目不难发现每种情况的答案是前面两种情况的答案之和,然后我们可以使用一个简单的斐波那契数列模拟这个青蛙跳台阶的问题。我们可以列出一个简单的公式即:

image-20211111214811283

代码实现:

class Solution {
public:
    int numWays(int n) {
​
            if(n==0) return 1;
            if(n==1) return 1;
            if(n>=2) return numWays(n-2)+numWays(n-1);
          
    }
};

这样是可以解出答案的,但聪明的同学会发现这样时间复杂度太高了,并且会进行大量的重复计算,做大量的无用功,这样的代码显得不是那么优雅,更致命的是这样递归调用会超出题目的时间限制

优化分析:

我们可以使用动态规划的思想,把之前运算过的结果存入数组,要用的话直接用下标读取,这样就可以大大降低时间复杂度。这里我们使用一个一维数组存储运算结果

代码实现:

class Solution {
public:
    int numWays(int n) {
​
        int a[1089849];// 定义一个一维数组
        if(n<=1) return 1;
        
        a[1]=1,a[0]=1;// 初始化必要的数据
        for(int i=2;i<=n;i++){
            a[i]=(a[i-1]+a[i-2])%1000000007;// 根据表达式计算,并把运算结果%1000000007,控制范围
            
        }
​
        return a[n];
​
    }
};

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

这里用画图再来模拟下程序的运算流程:

开始初始化数组:

image-20211111215702864

之后进行循环相加:

image-20211111215854633

这样就是一个大概的流程。

同学们也可以自己加一练习:

原问题连接:(leetcode-cn.com/problems/qi…)