【JZ-10-I】斐波那契数列(递归、动态规划)

题目

在这里插入图片描述
参考

方法一-递归法

f ( n ) f(n) f(n)的计算拆分成 f ( n − 1 ) f(n-1) f(n1) f ( n − 2 ) f(n-2) f(n2)两个子问题的计算,递归,以 f ( 0 ) f(0) f(0) f ( 1 ) f(1) f(1)为递归终止条件。
显然会进行大量重复计算,代码虽然简单但算法效率很低。

  • 时间复杂度(二叉树的节点总数): O ( 2 n ) O(2^n) O(2n),n 等于二叉树的高度
  • 空间复杂度: O ( n ) O(n) O(n),即树的高度

方法二-记忆化递归法

在递归法基础上用一个长度为 n 的数组存储 f ( 0 ) f(0) f(0) f ( n ) f(n) f(n)的值,避免了重复的递归计算。
但存储需要额外 O ( n ) O(n) O(n)的空间

方法三-动态规划

分治方法将问题划分为互不相交的子问题,递归求解子问题,再将它们的解组合起来求出原问题的解。在子问题重叠的情况下,即不同的子问题具有公共的子子问题时,分治算法会反复求解公共子子问题,而动态规划算法对每个子问题只求解一次
由于 f ( n ) f(n) f(n)只与 f ( n − 1 ) f(n-1) f(n1) f ( n − 2 ) f(n-2) f(n2)有关,因此只需要三个变量 s u m sum sum a a a b b b分别表示 f ( n ) f(n) f(n) f ( n − 1 ) f(n-1) f(n1) f ( n − 2 ) f(n-2) f(n2) s u m sum sum作为辅助变量使 a a a b b b交替前进
在这里插入图片描述

关于为什么要取模1e9+7(有时也会改为要求取模1e9 + 9和998244353):

都是小于 2 30 2^{30} 230的质数,因此取模后的两数相加在 int 范围内不会溢出,即 a + b < 2 31 a+b<2^{31} a+b<231;取模后的两数相乘在long long 范围内不会溢出,即 a b < 2 60 ab<2^{60} ab<260。另外,对质数取模能尽可能避免模数相同的数之间存在公因数,从而减少冲突,并且方便进行除法运算(因为除了0都存在逆元)。
在这里插入图片描述逆元的作用

class Solution {
    public int fib(int n) {
        int a = 0, b = 1, sum;
        for(int i = 0; i < n; i++){
            sum = (a + b)%1000000007;
            a = b;
            b = sum;
        }
        return a;
    }
}
  • 时间复杂度: O ( n ) O(n) O(n),循环 n 次,每轮循环内计算操作需要 O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( 1 ) O(1) O(1),3个变量使用常数大小的额外空间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值