2020-10-26 斐波那契数列

斐波那契数列

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
0 <= n <= 100

当数值较大时候会大数溢出,所以要对答案进行取模,而且使用递归的方法内存占用大,运行时间长,容易造成时间超时,所以采用动态规划的方法

  • 递归法:

原理: 把 f(n)f(n) 问题的计算拆分成 f(n-1)f(n−1) 和 f(n-2)f(n−2) 两个子问题的计算,并递归,以 f(0)f(0) 和 f(1)f(1) 为终止条件。
缺点: 大量重复的递归计算,例如 f(n)f(n) 和 f(n - 1)f(n−1) 两者向下递归都需要计算 f(n - 2)f(n−2) 的值。

  • 记忆化递归法:

原理: 在递归法的基础上,新建一个长度为 nn 的数组,用于在递归时存储 f(0)f(0) 至 f(n)f(n) 的数字值,重复遇到某数字时则直接从数组取用,避免了重复的递归计算。
缺点: 记忆化存储的数组需要使用 O(N)O(N) 的额外空间。

  • 动态规划:

原理: 以斐波那契数列性质 f(n + 1) = f(n) + f(n - 1)f(n+1)=f(n)+f(n−1) 为转移方程。
从计算效率、空间复杂度上看,动态规划是本题的最佳解法。

大数越界: 随着 nn 增大, f(n)f(n) 会超过 Int32 甚至 Int64 的取值范围,导致最终的返回值错误。

  • 求余运算规则

求余运算规则: 设正整数 x, y, px,y,p ,求余符号为⊙ ,则有 (x + y) ⊙p = (x⊙p + y⊙ p) ⊙p(x+y)⊙p=(x⊙p+y⊙p)⊙p 。
解析: 根据以上规则,可推出 f(n)⊙ p = [f(n-1)⊙ p + f(n-2) ⊙ p] ⊙ pf(n)⊙p=[f(n−1)⊙p+f(n−2)⊙p]⊙p ,从而可以在循环过程中每次计算 sum = a + b⊙ 1000000007 sum=a+b⊙1000000007 ,此操作与最终返回前取余等价。

题解:
Java:

class Solution {
    public int fib(int n) {
        if(n<=1){
            return n;
        }
        int[] arr = new int[n+1];
        arr[0] = 0;
        arr[1] = 1;
        for (int i = 2; i<=n;i++){
            arr[i] = arr[i-1] + arr[i-2];
            arr[i] = arr[i]%1000000007;
        }
        return arr[n];

    }
}
public class Solution {
    public int Fibonacci(int n) {
        if(n<=1){
            return n;
        }
//         int[] arr = new int[n+1];
//         arr[0] = 0;
//         arr[1] = 1;
        int first = 0;
        int second = 1;
        int res =0;
        for (int i = 2; i<=n;i++){
            res = (first +second)%1000000007;
            first =second;
            second = res;
        }
//         return arr[n];
       
      
        return res;
    
    }
}

javascrip


/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
     if(n<=1){
        return n;
    }
    // return Fibonacci(n-1)+Fibonacci(n-2);
    let array = [0,1];
    for(let i = 2;i<=n;i++){
        array[i] = array[i-1]+array[i-2];
        array[i] = array[i]%1000000007;
    }
    return array[n];

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值