细说剑指offer(1)_斐波那契数列之我真的懂吗?

1. 什么叫斐波那契数

1.1

形如:0,1,1,2,3,5,8,13。后面一个数等于前两数之和。

2. 题目描述

2.1

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39

3.解法1——递归

3.1 代码
public int Fibonacci(int n) {
        if(n == 0)
            return 0;
        if(n == 1)
            return 1;
        return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
3.2 分析

代码解读:

  • 采用递归的方法,调用自身返回。Java中每个线程都有自己的方法栈,从一开始的Fibonacci方法调用,依次将后面的方法调用入栈。直到n == 0,或者n == 1。然后方法栈里的方法出栈,并将结果返回到每个方法里。最后出栈的方法(也就是第一次调用)返回最终的结果。

复杂度解读:

  • 网上的图片
    可以看到,如果n为5,那么整个递归快进行了2的5次方次,时间复杂度约为O(n的平方)。我们知道2的次方越到后面越庞大。所以此算法效率低下。

4. 解法2——动态规划

4.1 代码
public int Fibonacci(int n) {
        if(n == 0)
            return 0;
        if(n == 1)
            return 1;
        int[] dp = new int[40];
        dp[0] = 0;
        dp[1] = 1;
        for(int i = 2; i <= n; i++){
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
4.2 分析

代码解读:

  • 采用动态规划的思想。用一个数组来保存中间结果,然后循环计算得到最终结果。

复杂度解读:

  • 代码中只循环了n次,所以关键操作也只执行了n此,时间复杂度为O(n)。

5. 解法3——迭代

5.1 代码
public int Fibonacci(int n) {
        if(n == 0)
            return 0;
        if(n == 1)
            return 1;
        
        int result = 0;
        int before = 0;
        int after = 1;
        
        for(int i = 0; i < n - 1; i++){ //注意,只循环n - 1次
            result = before + after;
            before = after;
            after = result;
        }
        
        return result;
    }
5.2 分析

代码解读:

  • 采用迭代的思想。只用3个变量保存结果,依次迭代,得到最终结果。

复杂度解读:

  • 代码中也循环了n次,所以关键操作也只执行了n此,时间复杂度为O(n)。但空间复杂度比解法2要好很多(试想一下,如果解法2n是二维数组,n更大呢?)。

6 总结

迭代和dp(动态规划)在时间上都优于递归,迭代在空间上优于dp。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值