🔗 第N个泰波那契数
📝 题目描述
泰波那契序列
,其中
现给你一个整数n
,请返回第n
个泰波那契数
📋 代码模版
java
class Solution {
public int tribonacci(int n) {
}
}
typescript
function tribonacci(n: number): number {
}
💡 提示
- 答案保证是一个32位整数,即
🚀 示例
🖊️ 题解
在解决这道题之前,建议先处理题目斐波那契数。
斐波那契数列的特点是前两个数字固定,后续每个数字都等于前两个数字的和。而本题中的泰波那契序列与之类似,特点是前三个数字固定,之后每个数字都等于前三个数字的和。因此,本题的解决方法几乎与题斐波那契数一致。
记忆化搜索
根据题目描述,本题的记忆化dfs
的递归公式为i
(2 < i <= n
)个数字的值⭐️。
java
class Solution {
public int tribonacci(int n) {
int[] memory = new int[n + 1];
return dfs(n, memory);
}
private int dfs(int i, int[] memory) {
if (i <= 1) {
return i;
}
if (i == 2) {
return 1;
}
if (memory[i] != 0) {
return memory[i];
}
return memory[i] = dfs(i - 1, memory) + dfs(i - 2, memory) + dfs(i - 3, memory);
}
}
typescript
function tribonacci(n: number): number {
const memory: number[] = [];
const dfs = (i: number): number => {
if (i <= 1) {
return i;
}
if (i == 2) {
return 1;
}
if (memory[i]) {
return memory[i];
}
return memory[i] = dfs(i - 1) + dfs(i - 2) + dfs(i - 3);
}
return dfs(n);
}
动态规划
根据以上dfs
的解法,我们可以很轻松地将其翻译成动态规划dp
解法,具体步骤如下。
- 状态定义:设
为一维数组,其中 代表⭐️泰波那契序列中第 i
个数字的值⭐️。 - 初始状态:根据边界条件,初始化
数组的前三项,即$dp[0] = 0, dp[1] = 1, dp[2] = 1 $。 - 状态转移方程:
,其中 。 - 返回值:
,即 的值。
java
class Solution {
public int tribonacci(int n) {
if (n <= 1) {
return n;
}
int[] dp = new int[n + 1];
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];
}
}
typescript
function tribonacci(n: number): number {
if (n <= 1) {
return n;
}
const dp: number[] = [];
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
for (let i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
return dp[n];
}
为了减小dp
算法的空间复杂度,我们可以采用状态压缩技巧,即用若干变量替代
java
class Solution {
public int tribonacci(int n) {
if (n <= 1) {
return n;
}
int pre1 = 0, pre2 = 1, cur = 1;
for (int i = 3; i <= n; i++) {
int sum = pre1 + pre2 + cur;
pre1 = pre2;
pre2 = cur;
cur = sum;
}
return cur;
}
}
typescript
function tribonacci(n: number): number {
if (n <= 1) {
return n;
}
let pre1 = 0, pre2 = 1, cur = 1;
for (let i = 3; i <= n; i++) {
const sum = pre1 + pre2 + cur;
pre1 = pre2;
pre2 = cur;
cur = sum;
}
return cur;
}
💭 复杂度分析
基于记忆化搜索
的解决方案的复杂度分析如下。
- 时间复杂度:
。 - 空间复杂度:
。
基于动态规划
的最优(状态压缩)解决方案的复杂度分析如下。
- 时间复杂度:
。 - 空间复杂度:
。