题目描述
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
示例 1 :
输入 :n = 4
输出 :4
解释 :
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4
示例 2 :
输入 :n = 25
输出:1389537
算法原理
这是一道使用动态规划解决的题目,所以按照 5 步来进行处理
- 创建一个 dp 数组,确定状态表示:状态表示指 dp 数组第 i 个元素代表着什么,在这道题目里,第 i 个元素 dpidpidpi 代表了第 i 个泰波那契数 TiT_iTi
- 确定状态转移方程:指第 i 个泰波那契数 TiT_iTi 的计算方式,题目中给出的是 Ti+3=Ti+Ti+1+Ti+2T_{i+3} = T_i + T_{i+1} + T_{i+2}Ti+3=Ti+Ti+1+Ti+2,只要让 i 减去 3,就可以得到 Ti=Ti−1+Ti−2+Ti−3T_{i} = T_{i-1} + T_{i-2} + T_{i-3}Ti=Ti−1+Ti−2+Ti−3,也就是说 dpi=dpi−1+dpi−2+dpi−3dpi = dpi - 1 + dpi - 2 + dpi - 3dpi=dpi−1+dpi−2+dpi−3
- 初始化:用来保证计算时数组不越界,如果 i = 0,dp0=dp−1+dp−2+dp−3dp0 = dp-1 + dp-2 + dp-3dp0=dp−1+dp−2+dp−3,这是会越界的,dp1,dp2dp1, dp2dp1,dp2 在计算时也是一样,所以要先初始化这三个值。题目中已经给出,dp0=T0=0,dp1=T1=1,dp2=T2=2dp0 = T_0 = 0,dp1 = T_1 = 1,dp2 = T_2= 2dp0=T0=0,dp1=T1=1,dp2=T2=2
- 填表顺序:由于新算出来的值依赖于之前的三个值,所以填表是从左向右的
- 返回值:题目要得到第 n 个泰波那契数的值,所以返回 dpndpndpn

代码
cpp
class Solution {
public:
int tribonacci(int n) {
int dp[38] = { 0 };
dp[0] = 0, dp[1] = 1, dp[2] = 1;
for (int i = 3;i <= n;++i)
{
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
return dp[n];
}
};
空间优化
以计算第 5 个泰波那契数 T5=7T_5 = 7T5=7 为例:

当计算出 T3=2T_3 = 2T3=2,计算 T4=4T_4 = 4T4=4 时,可以发现只需要用到 T1,T2,T3T_1, T_2,T_3T1,T2,T3。 T0=0T_0 = 0T0=0 已经不需要使用了。因此每当计算出一个泰波那契数的时候,之前算出来过的一个数就可以丢弃了
在这样的条件下,不需要使用一个数组来保存得到的所有泰波那契数,只要用三个变量 a, b, c 保存计算 TiT_iTi 时需要的数 Ti−1,Ti−2,Ti−3T_{i-1}, T_{i-2}, T_{i-3}Ti−1,Ti−2,Ti−3 即可
优化后的代码
cpp
class Solution {
public:
int tribonacci(int n) {
if (n == 0) return 0;
else if (n == 1 || n == 2) return 1;
int a = 0, b = 1, c = 1, d = 0;
for (int i = 3;i <= n;++i)
{
d = a + b + c;
a = b;
b = c;
c = d;
}
return d;
}
};