题目描述
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示:0 <= n <= 100
方法一:递归
题目分析,斐波那契数列公式为:f[n] = f[n-1] + f[n-2], 初始值f[0]=0, f[1]=1,目标求f[n]
class Solution {
public:
int Fibonacci(int n) {
if(n == 0 || n == 1)
return n;
return Fibonacci(n-1) + Fibonacci(n-2);
}
};
优点,代码简单好写,缺点:慢,会超时
时间复杂度:O(2^n)
空间复杂度:O(n) 递归栈的空间
方法二:动态规划
用一个数组把计算过程保存下来,就不需要做太多的重复运算
class Solution {
public:
int Fibonacci(int n) {
vector<int> dp(n+1, 0);
dp[1] = 1;
for(int i=2; i<=n; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
};
时间复杂度:O(n)
空间复杂度:O(n)
继续优化
发现计算f[5]的时候只用到了f[4]和f[3], 没有用到f[2]...f[0],所以保存f[2]..f[0]是浪费了空间。
只需要用3个变量即可。
class Solution {
public:
int Fibonacci(int n) {
if(n == 0 || n == 1)
return n;
int a = 0, b = 1, c;
for(int i=2; i<=n; i++){
c = a + b;
a = b;
b = c;
}
return c;
}
};
时间复杂度:O(n)
空间复杂度:O(1)