1.1 斐波那契数列模型:LeetCode 1137.第 N 个泰波那契数
动态规划与滚动数组优化:LeetCode 1137.第 N 个泰波那契数
1. 题目链接
LeetCode 1137. 第 N 个泰波那契数
题目要求:计算第 n
个泰波那契数(Tribonacci Number)。泰波那契数列的定义如下:
T0 = 0, T1 = 1, T2 = 1
Tn+3 = Tn + Tn+1 + Tn+2
(当n ≥ 0
时)
2. 题目描述
- 输入:整数
n
(例如n = 4
)。 - 输出:第
n
个泰波那契数(例如T4 = 4
)。 - 约束条件:
0 ≤ n ≤ 37
- 结果保证在 32 位整数范围内(即
≤ 2^31 - 1
)。
3. 示例分析
示例 1:
输入:n = 4
输出:4
分步计算:
T0 = 0
T1 = 1
T2 = 1
T3 = T0 + T1 + T2 = 0 + 1 + 1 = 2
T4 = T1 + T2 + T3 = 1 + 1 + 2 = 4
示例 2:
输入:n = 25
输出:1389537
4. 算法思路
动态规划与滚动数组优化
-
问题特性:
- 泰波那契数的递推公式依赖前三个状态,适合用动态规划解决。
- 直接递归会重复计算子问题(时间复杂度
O(3^n)
),需优化。
-
动态规划递推:
- 定义状态
dp[i]
表示第i
个泰波那契数。 - 递推公式:
dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
。
- 定义状态
-
滚动数组优化:
- 观察发现,计算
dp[i]
仅需前三个值dp[i-1]
、dp[i-2]
、dp[i-3]
。 - 用三个变量
dp1
、dp2
、dp3
代替数组,空间复杂度从O(n)
降为O(1)
。
- 观察发现,计算
具体步骤
- 初始化:
T0 = 0
,T1 = 1
,T2 = 1
。
- 递推计算:
- 从
i = 3
到n
,依次更新当前值tn = dp1 + dp2 + dp3
。 - 滚动更新变量:
dp1 = dp2
,dp2 = dp3
,dp3 = tn
。
- 从
5. 边界条件与注意事项
-
边界处理:
n = 0
时直接返回0
。n = 1
或n = 2
时直接返回1
。
-
变量初始化顺序:
dp1
、dp2
、dp3
分别对应T0
、T1
、T2
。
-
循环范围:
- 若
n < 3
,直接返回初始值,无需进入循环。
- 若
-
整数溢出问题:
- 题目保证结果在 32 位整数范围内,无需额外处理。
-
时间复杂度:
O(n)
,遍历n-2
次。
6. 代码实现与逐行解析
class Solution {
public:
int tribonacci(int n) {
if (n == 0) return 0; // 边界条件:T0 = 0
if (n == 1 || n == 2) return 1; // 边界条件:T1=T2=1
// 初始化滚动数组(对应 T0, T1, T2)
int dp1 = 0, dp2 = 1, dp3 = 1, tn = 0;
for (int i = 3; i <= n; i++) {
tn = dp1 + dp2 + dp3; // 计算当前值 T_i
// 滚动更新:dp1 -> T_{i-2}, dp2 -> T_{i-1}, dp3 -> T_i
dp1 = dp2;
dp2 = dp3;
dp3 = tn;
}
return tn; // 返回 T_n
}
};
代码解析
-
边界处理:
n = 0
、n = 1
、n = 2
直接返回预定义值。
-
变量初始化:
dp1 = 0
(对应T0
),dp2 = 1
(对应T1
),dp3 = 1
(对应T2
)。
-
循环递推:
- 从
i = 3
开始,计算tn = dp1 + dp2 + dp3
(即T_i
)。 - 更新变量:
dp1
更新为原来的dp2
(即T_{i-2} = T_{i-1}
)。dp2
更新为原来的dp3
(即T_{i-1} = T_i
)。dp3
更新为tn
(即T_i
)。
- 从
-
返回值:
- 循环结束时,
tn
即为T_n
。
- 循环结束时,
总结
通过滚动数组优化,将动态规划的空间复杂度从 O(n)
降至 O(1)
,同时保持了时间效率。该算法高效解决了泰波那契数的计算问题,适用于大规模 n
的场景(尽管题目约束 n ≤ 37
)。此方法可推广至其他类似递推问题(如斐波那契数列、爬楼梯问题等),核心在于识别状态依赖关系并优化空间使用。