LC 1137.N-th Tribonacci Number

题目描述

这是 LeetCode 上的 1137. 第 N 个泰波那契数 ,难度为简单

泰波那契序列 Tn 定义如下:

T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2

给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

示例 1:

1
2
3
4
5
输入:n = 4
输出:4
解释:
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4

示例 2:

1
2
输入:n = 25
输出:1389537

提示:

  • 0 <= n <= 37
  • 答案保证是一个 32 位整数,即 answer <= 2^31 - 1

解答

方法一:动态规划

给出了递推的方程之后,就是给出了状态转移方程,直接类似斐波那契数列模拟一下,为了不用处理特殊情况,向前递推两项。

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public int tribonacci(int n) {
int t0 = 1, t1 = 0, t2 = 0; // 求出T0的前两项,此时的t2就是给的条件中的T0
for (int i = 1; i <= n; ++i) {
int tmp = t2;
t2 += t0 + t1;
t0 = t1;
t1 = tmp;
}
return t2;
}
}
  • 时间复杂度\(O(n)\) ,其中 n 为数字 n 的大小。

  • 空间复杂度\(O(1)\)

方法二:矩阵快速幂

@Source:题解来源

不了解矩阵快速幂的可以参看LC 0070.Climbing Stairs - Abel's Blog (chen-hu快速幂,使用矩阵快速幂可以降低时间复杂度。

首先构建一个递推关系的矩阵形式: \[ \begin{bmatrix} 1 & 1 & 1 \\ 1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} T(n) \\ T(n - 1) \\ T(n - 2) \end{bmatrix} = \begin{bmatrix} T(n) + T(n - 1) + T(n - 2) \\ T(n) \\ T(n - 1) \end{bmatrix} = \begin{bmatrix} T(n + 1) \\ T(n) \\ T(n - 1) \end{bmatrix} \] 因此: \[ \begin{bmatrix} T(n + 2) \\ T(n + 1) \\ T(n) \end{bmatrix} = \begin{bmatrix} 1 & 1 & 1 \\ 1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix} ^n \begin{bmatrix} T(2) \\ T(1) \\ T(0) \end{bmatrix} \] 令: \[ M = \begin{bmatrix} 1 & 1 & 1 \\ 1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix} \] 因此只要能够快速计算矩阵 Mn 次幂,就可以快速得到 T(n) 的值。如果直接求 \(M^n\) ,时间复杂度为 \(O(n)\) ,可以定义矩阵乘法,然后用快速幂来加速计算 \(M^n\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Solution {
public int tribonacci(int n) {
if (n == 0) {
return 0;
}
if (n <= 2) {
return 1;
}
int[][] q = {{1, 1, 1}, {1, 0, 0}, {0, 1, 0}};
int[][] res = pow(q, n);
return res[0][2];
}

public int[][] pow(int[][] a, int n) {
int[][] ret = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
while (n > 0) {
if ((n & 1) == 1) { // 当末尾的二进制位为非0的时候才需要乘
ret = multiply(ret, a);
}
n >>= 1;
a = multiply(a, a); // 计算下一个项
}
return ret;
}

public int[][] multiply(int[][] a, int[][] b) {
int[][] c = new int[3][3];
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
}
}
return c;
}
}
  • 时间复杂度\(O(\log n)\),其中 n 为数字 n 的大小,每次数字都折半。

  • 空间复杂度\(O(1)\)

每题一图


LC 1137.N-th Tribonacci Number
https://chen-huaneng.github.io/2023/12/11/2023-12-11-2023-12-11-lc-1137/
作者
Abel
发布于
2023年12月11日
更新于
2023年12月11日
许可协议