14. leetCode-剑指Offer10-I斐波那契数列

剑指Offer10-I斐波那契数列

1. 问题描述

  1. 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:

    F(0) = 0,   F(1) = 1
    F(N) = F(N - 1) + F(N - 2), 其中 N > 1
    
  2. 斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

  3. 示例 1:

    输入:n = 2
    输出:1
    
  4. 示例 2:

    输入:n = 5
    输出:5
    
  5. 提示:

    0 <= n <= 100
    

2. 代码实现

斐波那契数列的定义是 f(n + 1) = f(n) + f(n - 1) ,生成第 n项的做法有以下几种:

  1. 递归法:

    1. 原理: 把 f(n)f(n) 问题的计算拆分成 f(n-1)和 f(n-2)两个子问题的计算,并递归,以 f(0)和 f(1)为终止条件。
    2. 缺点: 大量重复的递归计算,例如 f(n)和 f(n - 1)两者向下递归需要各自计算 f(n - 2)的值。
  2. 动态规划:
    2. 原理: 以斐波那契数列性质 f(n + 1) = f(n) + f(n - 1) 为转移方程。
    3. 从计算效率、空间复杂度上看,动态规划是本题的最佳解法。

作者:jyd

2.1 方法一

递归法,超出时间限制;哈哈哈哈哈

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

动态规划,使用质数1000000007取余

class Solution {
    public int fib(int n) {
        if(n == 0){
            return 0;
        }
        if(n == 1){
            return 1;
        }
        // 这里n+2 是为了防止数组下标越界
        int[] arr = new int[n+2];
        arr[0] = 0;
        arr[1] = 1;

        // 具体的逻辑
        for(int i=2;i<=n;i++){
            arr[i] = arr[i-1] + arr[i-2];
            arr[i] %= 1000000007;
        }

        return arr[n];
    }
}

2.2 方法二

动态规划

class Solution {
    public int fib(int n) {
       int a = 0;
        int b =1;
        int sum;
        for (int i = 0; i < n; i++) {
            sum = (a + b) % 1000000007;
            // 后移一步
            a = b;
            b = sum;
        }
        return a;

    }
}

3. 结果分析

方法一:

  1. 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
  2. 内存消耗:36.7 MB, 在所有 Java 提交中击败了7.12%的用户

方法二:

  1. 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
  2. 内存消耗:36.5 MB, 在所有 Java 提交中击败了45.27%的用户


版权声明:本文为weixin_45267102原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。