思路:

题目的主要信息:

  • 斐波那契数列每项的公式为:,从0开始,
  • 求出斐波那契数列的第n项
  • n最大不超过39,结果不会超出int的范围,不用考虑long long

方法一:递归
具体做法:
根据公式,每次返回,结束递归的点就是1或者0

class Solution {
public:
    int Fibonacci(int n) {
        if (n <= 1)    //从0开始,第0项是0,第一项是1
             return n;
        else
            return Fibonacci(n - 1) + Fibonacci(n - 2); //根据公式递归调用函数
        return 0;
    }
};

复杂度分析:

  • 时间复杂度:,每个递归会调用两个递归,因此呈现2的指数增长
  • 空间复杂度:, 递归栈的最大深度

方法二:递归优化(记忆化递归)
具体做法:
在递归法的基础上,新建一个长度为 n 的数组,用于在递归时存储f(0)至f(n)的数字值,重复遇到某数字则直接从数组取用,避免了重复的递归计算。
图片说明

class Solution {
public:
    int dp[40] = {0}; //记忆每次已有的结果
    int Fibonacci(int n) {
        if (n <= 1){//从0开始,第0项是0,第一项是1
            dp[n] = n;
            return n;
        }
        else{
            int a, b;
            //若是数组中记录了值,直接用省去递归
            if(dp[n - 1] == 0)
                a = Fibonacci(n - 1);
            else
                a = dp[n - 1];
            if(dp[n - 2] == 0)
                b = Fibonacci(n - 2);
            else
                b = dp[n - 2];
            return a + b;
        }
        return 0;
    }
};

复杂度分析:

  • 时间复杂度:,每个数只有一次计算,没有多余的运算
  • 空间复杂度:,使用了辅助数组dp

方法三:动态规划
具体做法:
创建一个n+1大小的辅助数组dp,初始化第0位为0,第1位为1,然后根据公式依次往后相加即可得到后面的值,数组最后的下标n即为所求。

class Solution {
public:
    int Fibonacci(int n) {
        if (n <= 1)    
             return n;
        vector<int> dp(n + 1);
        dp[0] = 0;   //从0开始,第0项是0,第一项是1
        dp[1] = 1;
        for (int i = 2; i <= n; i++)
            dp[i] = dp[i - 1] + dp[i - 2]; //公式相加
        return dp[n];
    }
};

复杂度分析:

  • 时间复杂度:,一次遍历
  • 空间复杂度:,创建了一个大小为n+1的辅助数组

方法四:动态规划空间优化
具体做法:
动态规划申请了一个数组,但是我们可以发现其实每次需要的只是i-1和i-2的值,我们可以用两个变量保存该值,每次更新即可。
图片说明

class Solution {
public:
    int Fibonacci(int n) {
        if (n <= 1)    //从0开始,第0项是0,第一项是1
             return n;
        int i_2 = 0;  //分别记录i-1与i-2的值
        int i_1 = 1;
        int res = 0;
        for (int i = 2; i <= n; i++){
            res = i_1 + i_2;
            i_2 = i_1;  //更新i-1与i-2
            i_1 = res;
        }
        return res;
    }
};

复杂度分析:

  • 时间复杂度:,其中n为输入的数,一次遍历
  • 空间复杂度:,未申请空间