[每日算法 - 华为机试] 剑指 Offer 10- II. 青蛙跳台阶问题

入口

力扣icon-default.png?t=N7T8https://leetcode.cn/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/

题目描述

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

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

示例 1:

        输入:n = 2
        输出:2
示例 2:

        输入:n = 7
        输出:21
示例 3:

        输入:n = 0
        输出:1
提示:

        0 <= n <= 100

斐波那契数列 

青蛙跳台阶问题是一种经典的动态规划问题,可以通过类比斐波那契数列来求解。问题的关键在于理解青蛙跳跃的可能路径:

  • 第1级台阶:只有 1 种方法,即青蛙直接跳1级到达目标。

  • 第2级台阶:有 2 种方法

    1. 跳1级,然后再跳1级:青蛙可以选择先跳到第1级台阶,然后再跳1级到第2级。
    2. 直接跳2级:青蛙可以选择直接从地面跳到第2级。
  • 第n级台阶(n > 2):对于任意第n级台阶,青蛙有两种可能的最后一步:

    1. 从第(n-1)级台阶跳1级:青蛙可以先跳到第(n-1)级台阶,然后再跳1级到达第n级。
    2. 从第(n-2)级台阶跳2级:青蛙可以先跳到第(n-2)级台阶,然后直接跳2级到达第n级。

这个思路的核心在于,每个台阶的到达方法数是基于前两个台阶的方法数之和,因为青蛙可以选择跳1级或者2级。

递推公式:F(n) = F(n-1) + F(n-2)

方法一:递归

 Java示例

class Solution {
    public int climbStairs(int n) {
        if(n==1 || n==2){
            return n;
        }
        return climbStairs(n-1) + climbStairs(n-2);
    }
}

时间复杂度:O(2^n)

空间复杂度:O(n)

方法二:记忆递归

方法一缺点: 多了很多重复计算(如红框圈出来的地方),记忆递归的讲每次计算结果存储,不再重复计算。

复杂度分析 方法一复杂度分析

 Java示例

class Solution {
    public int climbStairs(int n) {
        int memo[] = new int[n+1];//存储计算结果
        return climb(memo,n);
    }
    public int climb(int[] memo,int n){
        if(n==1 || n==2){
            memo[n] = n;
        }
        if(memo[n] == 0){
            memo[n] = climb(memo,n-1) + climb(memo,n-2);
        }
        return memo[n];
    }
}

时间复杂度:O(n)

空间复杂度:O(n)

方法三:动态规划

Java示例

class Solution {
    public int climbStairs(int n) {
        if(n==1 || n==2){
           return n;
        }
        int dp[] = new int[n+1];
        dp[1] = 1;
        dp[2] = 2;
        for(int i=3;i<=n;i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n-1] + dp[n-2];
    }
}

时间复杂度:O(n)

空间复杂度:O(n)

方法四:斐波那契数列

在方法一的dp数组中只有两个元素被使用,现在将浪费的空间优化掉,将空间复杂度降为O(1)

Java示例

class Solution {
    public int climbStairs(int n) {
        if(n==1 || n==2){
           return n;
        }
        int first=1;
        int second = 2;
        for(int i=3;i<n;i++){
           int third = first + second;
           first = second;
           second = third;
        }
        return first + second;
    }
}

时间复杂度:O(n)

空间复杂度:O(1)

posted @ 2023-07-03 16:37  yihuiComeOn  阅读(41)  评论(0)    收藏  举报  来源