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

题目描述

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

n<=39

过程:

0 1 1 2 3 5 8……

这题我知道绝对要用递归,这样才帅。

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

优点,代码简单好写,缺点:慢,会超时
时间复杂度:O(2^n)
空间复杂度:递归栈的空间

再去看看题解……

原来我想到的方法又是最烂的啊……


方法二:记忆化搜索

拿求f[5] 举例

JZ7:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。_第1张图片

通过图会发现,初始方法中存在很多重复计算,因为为了改进,就把计算过的保存下来。
那么用什么保存呢?一般会想到map, 但是此处不用牛刀,此处用数组就好了。

public class Solution {
    public int Fibonacci(int n) {
        int ans[] = new int[40];
        ans[0]=0;
        ans[1]=1;
        for(int i=2;i<=n;i++){
            ans[i]=ans[i-1]+ans[i-2];
        }
        return ans[n];
    }
}

时间复杂度:O(n)
空间复杂度:O(n) 


优化存储

其实我们可以发现每次就用到了最近的两个数,所以我们可以只存储最近的两个数

  • sum 存储第 n 项的值
  • one 存储第  n-2 项的值
  • two 存储第  n-1 项的值
public class Solution {
    public int Fibonacci(int n) {
        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        int sum = 0;
        int one = 0;
        int two = 1;
        for(int i=2;i

时间复杂度:O(n)
空间复杂度:O(1)


持续优化

观察上一版发现,sum 只在每次计算第 n 项的时候用一下,其实还可以利用 sum 存储第 n-1 项,例如当计算完 f(5) 时 sum 存储的是 f(5) 的值,当需要计算 f(6) 时,f(6) = f(5) + f(4),sum 存储的 f(5),f(4) 存储在 one 中,由 f(5)-f(3) 得到。

本来的三个变量存储,现在只有俩变量存储。

public class Solution {
    public int Fibonacci(int n) {
        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        int sum = 1;
        int one = 0;
        for(int i=2;i

时间复杂度:O(n)
空间复杂度:O(1)

你可能感兴趣的:(数据结构与算法,&,刷题)