Leetcode509. 斐波那契数列
斐波那契数 (通常用 F(n)
表示)形成的序列称为 斐波那契数列 。该数列由 0
和 1
开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n
,请计算 F(n)
。
示例:
输入:n = 3 输出:2 解释:F(3) = F(2) + F(1) = 1 + 1 = 2:
提示:
0 <= n <= 30
来源:力扣https://leetcode-cn.com/problems/fibonacci-number/动态规划入门题,在递归求解的过程中存在着重复的子问题。虽然已经有很简洁完善的答案,但对初学者而言,理解这个答案是如何产生的仍然是是必要的思考过程。
方法一:O(n)空间复杂度
用数组储存重复的子问题答案
class Solution {
public:
int fib(int n) {
if(n == 0 || n == 1) return n;
vector<int>fibtable(32,0);
fibtable[1] = 1;
for(int i = 2; i <= n; i++){
fibtable[i] = fibtable[i - 1] + fibtable[i - 2];
}
return fibtable[n];
}
};
方法二:O(1)空间复杂度(动态规划的状态压缩)
进一步观察可以发现,对于我们想要得到的fib(n),其实只与fib(n - 1) 和fib(n - 2)有关。因此不必存下之前所有的fib(i),只要用三个变量就可以。int a 存储fib(n - 2),int b 存储fib(n - 1),int sum 是传递状态的中间变量。
class Solution {
public:
int fib(int n) {
if(n == 0 || n == 1) return n;
int a = 0;
int b = 1;
int sum = 1;
for(int i = 2; i < n; i++){
sum = a + b;
a = b;
b = sum;
}
return a + b;
}
};
进一步地,其实sum这个中间变量可以省去,此种实现也是最常见的。
class Solution {
public:
int fib(int n) {
if(n == 0 || n == 1) return n;
int a = 0, b = 1;
for(int i = 2; i < n; i++){
b = a + b;
a = b - a;
}
return a + b;
}
};
leetcode1137题和本题非常相似。
Leetcode1137. 第N个泰波那契数
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
输入:n = 4 输出:4 解释: T_3 = 0 + 1 + 1 = 2 T_4 = 1 + 1 + 2 = 4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-th-tribonacci-number
代码:
class Solution {
public:
int tribonacci(int n) {
if(n == 0) return 0;
if(n == 1 || n == 2) return 1;
int a = 0;
int b = 1;
int c = 1;
int sum;
for(int i = 3; i < n; i++){
sum = a + b + c;
a = b;
b = c;
c = sum;
}
return a + b + c;
}
};