斐波那契数列

本文探讨了如何避免递归算法的效率低下,通过优化递归方法(记忆化搜索)和引入动态规划,详细讲解了斐波那契数列的高效求解。分别介绍了递归的优化版本,以及如何通过循环实现的动态规划算法,对比了它们的时间复杂度和空间复杂度。
摘要由CSDN通过智能技术生成

题目:

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

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

1.递归算法(不建议使用):

public int fib(int n){
        if(n==0){
            return 0;
        }
        if(n<=2&&n>0){
            return 1;
        }
        return fib(n-1)+fib(n-2);

    }
  • 原理: 把 f(n)f(n) 问题的计算拆分成 f(n-1)f(n−1) 和 f(n-2)f(n−2) 两个子问题的计算,并递归,以 f(0)f(0) 和 f(1)f(1) 为终止条件。
  • 缺点: 递归n次,时间复杂度O(2^n),大量重复的递归计算,过程过于繁琐,例如 f(n)f(n) 和 f(n - 1)f(n−1) 两者向下递归需要 各自计算 f(n - 2)f(n−2) 的值。

2.优化递归(利用数组保存重复数字):

public int fib1(int n) {
       int[] num=new int[50];
       // 结束条件
       if(n==0){
           return 0;
       }
       if (n == 1 || n == 2) {
           return 1;
       }
       // 检查数组中有没有计算好的结果,如果有,直接返回结果,如果没有进行计算,并存入数组
       // 1如果有,直接返回结果
       if (num[n] != 0) {
           return num[n];
       }
       // 2如果没有, 进行计算,并存入数组
       int x = fib1( n - 1 ) + fib1( n - 2 );
       num[n] = x;
       return x;
   }
  • 原理:利用数组将重复元素保存下来,减少重复递归算法
  • 缺点:记忆化存储需要使用 O(N) 的额外空间。

3.动态规划(递归算法)

 public int fib2(int n) {
        int a = 0, b = 1;
        int sum = 0;
        for(int i = 0; i < n; i++){
          sum = (a + b) % 1000000007;
            a = b;
            b = sum;
        }
        return sum;
    }
  • 时间复杂度 O(N) : 计算 f(n) 需循环 n 次,每轮循环内计算操作使用 O(1)。
  • 空间复杂度 O(1) : 几个标志变量使用常数大小的额外空间。
    注意:
    取模 1e9+7(1000000007)是为了限制最后的结果,防止数据太大无法保存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~四时春~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值