题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
n<=39
解题思路
方法一:递归
1、思路:经典递归题目,两行代码搞定。
2、代码:
class Solution {
public:
int Fibonacci(int n) {
if (n == 0 || n == 1) return n;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
};
3、复杂度:
时间复杂度:O();
空间复杂度:递归栈的空间。
方法二:记忆化搜索
1、思路:保存每次计算过的n,避免重复计算。
2、代码:
class Solution {
public:
int Fib(vector<int> &ret, int n) {
if (n == 0 || n == 1) return n;
if(ret[n] != -1) return ret[n];
return ret[n] = Fib(ret, n - 1) + Fib(ret, n - 2);
}
int Fibonacci(int n) {
vector<int> ret(40, -1);
return Fib(ret, n);
}
};
3、复杂度:
时间复杂度:O(n),对于每个n都只计算了一次;
空间复杂度:O(n) + 递归栈的空间。
方法三:动态规划
1、思路:前面两种方法都是通过自顶向下递归,然后再自底向上回溯合并子树来求解答案,而动态规划自底向上,可以直接从子树求解答案,优化掉了递归栈的空间。
2、代码:
class Solution {
public:
int Fibonacci(int n) {
vector<int> ret(n + 1, 0);
ret[1] = 1;
for (int i = 2; i <= n; i++) {
ret[i] = ret[i - 1] + ret[i - 2];
}
return ret[n];
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n)。
方法四:动态规划空间优化
1、思路:在计算斐波那契数列第n项的时候,不需要用到前面的n-3项,因此可以释放空间,通过两个变量就可以完成求解。
2、代码:
class Solution {
public:
int Fibonacci(int n) {
if (n == 0 || n == 1) return n;
int a = 0, b = 1, i;
for (i = 2; i <= n; i++) {
b = a + b;
a = b - a;
}
return b;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(1)。
方法五:矩阵法
1、思路:通过公式推导转化成矩阵运算,需要用矩阵快速幂来求解矩阵幂乘。
2、代码:
3、复杂度:
时间复杂度:O();
空间复杂度:O(1)。
方法六:通项公式
1、思路:用“待定系数法”推导出斐波那契数列的通项公式。
2、代码:
3、复杂度:
时间复杂度:O();
空间复杂度:O(1)。