Skip to content

Commit a12283c

Browse files
authored
feat: add solutions to lc problem: No.1137 (#1618)
No.1137.N-th Tribonacci Number
1 parent 4078710 commit a12283c

File tree

8 files changed

+754
-43
lines changed

8 files changed

+754
-43
lines changed

solution/1100-1199/1137.N-th Tribonacci Number/README.md

+279
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,32 @@ T_4 = 1 + 1 + 2 = 4
5252

5353
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为给定的整数。
5454

55+
**方法二:矩阵快速幂加速递推**
56+
57+
我们设 $Tib(n)$ 表示一个 $1 \times 3$ 的矩阵 $\begin{bmatrix} T_n & T_{n - 1} & T_{n - 2} \end{bmatrix}$,其中 $T_n$, $T_{n - 1}$ 和 $T_{n - 2}$ 分别表示第 $n$ 个、第 $n - 1$ 个和第 $n - 2$ 个泰波那契数。
58+
59+
我们希望根据 $Tib(n-1) = \begin{bmatrix} T_{n - 1} & T_{n - 2} & T_{n - 3} \end{bmatrix}$ 推出 $Tib(n)$。也即是说,我们需要一个矩阵 $base$,使得 $Tib(n - 1) \times base = Tib(n)$,即:
60+
61+
$$
62+
\begin{bmatrix}
63+
T_{n - 1} & T_{n - 2} & T_{n - 3}
64+
\end{bmatrix} \times base = \begin{bmatrix} T_n & T_{n - 1} & T_{n - 2} \end{bmatrix}
65+
$$
66+
67+
由于 $T_n = T_{n - 1} + T_{n - 2} + T_{n - 3}$,所以矩阵 $base$ 为:
68+
69+
$$
70+
\begin{bmatrix}
71+
1 & 1 & 0 \\
72+
1 & 0 & 1 \\
73+
1 & 0 & 0
74+
\end{bmatrix}
75+
$$
76+
77+
我们定义初始矩阵 $res = \begin{bmatrix} 1 & 1 & 0 \end{bmatrix}$,那么 $T_n$ 等于 $res$ 乘以 $base^{n - 3}$ 的结果矩阵中所有元素之和。使用矩阵快速幂求解即可。
78+
79+
时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。
80+
5581
<!-- tabs:start -->
5682

5783
### **Python3**
@@ -67,6 +93,35 @@ class Solution:
6793
return a
6894
```
6995

96+
```python
97+
class Solution:
98+
def tribonacci(self, n: int) -> int:
99+
def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]:
100+
m, n = len(a), len(b[0])
101+
c = [[0] * n for _ in range(m)]
102+
for i in range(m):
103+
for j in range(n):
104+
for k in range(len(a[0])):
105+
c[i][j] = c[i][j] + a[i][k] * b[k][j]
106+
return c
107+
108+
def pow(a: List[List[int]], n: int) -> List[List[int]]:
109+
res = [[1, 1, 0]]
110+
while n:
111+
if n & 1:
112+
res = mul(res, a)
113+
n >>= 1
114+
a = mul(a, a)
115+
return res
116+
117+
if n == 0:
118+
return 0
119+
if n < 3:
120+
return 1
121+
a = [[1, 1, 0], [1, 0, 1], [1, 0, 0]]
122+
return sum(pow(a, n - 3)[0])
123+
```
124+
70125
### **Java**
71126

72127
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -86,6 +141,51 @@ class Solution {
86141
}
87142
```
88143

144+
```java
145+
class Solution {
146+
public int tribonacci(int n) {
147+
if (n == 0) {
148+
return 0;
149+
}
150+
if (n < 3) {
151+
return 1;
152+
}
153+
int[][] a = {{1, 1, 0}, {1, 0, 1}, {1, 0, 0}};
154+
int[][] res = pow(a, n - 3);
155+
int ans = 0;
156+
for (int x : res[0]) {
157+
ans += x;
158+
}
159+
return ans;
160+
}
161+
162+
private int[][] mul(int[][] a, int[][] b) {
163+
int m = a.length, n = b[0].length;
164+
int[][] c = new int[m][n];
165+
for (int i = 0; i < m; ++i) {
166+
for (int j = 0; j < n; ++j) {
167+
for (int k = 0; k < b.length; ++k) {
168+
c[i][j] += a[i][k] * b[k][j];
169+
}
170+
}
171+
}
172+
return c;
173+
}
174+
175+
private int[][] pow(int[][] a, int n) {
176+
int[][] res = {{1, 1, 0}};
177+
while (n > 0) {
178+
if ((n & 1) == 1) {
179+
res = mul(res, a);
180+
}
181+
a = mul(a, a);
182+
n >>= 1;
183+
}
184+
return res;
185+
}
186+
}
187+
```
188+
89189
### **C++**
90190

91191
```cpp
@@ -104,6 +204,50 @@ public:
104204
};
105205
```
106206
207+
```cpp
208+
class Solution {
209+
public:
210+
int tribonacci(int n) {
211+
if (n == 0) {
212+
return 0;
213+
}
214+
if (n < 3) {
215+
return 1;
216+
}
217+
vector<vector<ll>> a = {{1, 1, 0}, {1, 0, 1}, {1, 0, 0}};
218+
vector<vector<ll>> res = pow(a, n - 3);
219+
return accumulate(res[0].begin(), res[0].end(), 0);
220+
}
221+
222+
private:
223+
using ll = long long;
224+
vector<vector<ll>> mul(vector<vector<ll>>& a, vector<vector<ll>>& b) {
225+
int m = a.size(), n = b[0].size();
226+
vector<vector<ll>> c(m, vector<ll>(n));
227+
for (int i = 0; i < m; ++i) {
228+
for (int j = 0; j < n; ++j) {
229+
for (int k = 0; k < b.size(); ++k) {
230+
c[i][j] += a[i][k] * b[k][j];
231+
}
232+
}
233+
}
234+
return c;
235+
}
236+
237+
vector<vector<ll>> pow(vector<vector<ll>>& a, int n) {
238+
vector<vector<ll>> res = {{1, 1, 0}};
239+
while (n) {
240+
if (n & 1) {
241+
res = mul(res, a);
242+
}
243+
a = mul(a, a);
244+
n >>= 1;
245+
}
246+
return res;
247+
}
248+
};
249+
```
250+
107251
### **Go**
108252

109253
```go
@@ -116,6 +260,51 @@ func tribonacci(n int) int {
116260
}
117261
```
118262

263+
```go
264+
func tribonacci(n int) (ans int) {
265+
if n == 0 {
266+
return 0
267+
}
268+
if n < 3 {
269+
return 1
270+
}
271+
a := [][]int{{1, 1, 0}, {1, 0, 1}, {1, 0, 0}}
272+
res := pow(a, n-3)
273+
for _, x := range res[0] {
274+
ans += x
275+
}
276+
return
277+
}
278+
279+
func mul(a, b [][]int) [][]int {
280+
m, n := len(a), len(b[0])
281+
c := make([][]int, m)
282+
for i := range c {
283+
c[i] = make([]int, n)
284+
}
285+
for i := 0; i < m; i++ {
286+
for j := 0; j < n; j++ {
287+
for k := 0; k < len(b); k++ {
288+
c[i][j] += a[i][k] * b[k][j]
289+
}
290+
}
291+
}
292+
return c
293+
}
294+
295+
func pow(a [][]int, n int) [][]int {
296+
res := [][]int{{1, 1, 0}}
297+
for n > 0 {
298+
if n&1 == 1 {
299+
res = mul(res, a)
300+
}
301+
a = mul(a, a)
302+
n >>= 1
303+
}
304+
return res
305+
}
306+
```
307+
119308
### **JavaScript**
120309

121310
```js
@@ -137,6 +326,96 @@ var tribonacci = function (n) {
137326
};
138327
```
139328

329+
```js
330+
/**
331+
* @param {number} n
332+
* @return {number}
333+
*/
334+
var tribonacci = function (n) {
335+
if (n === 0) {
336+
return 0;
337+
}
338+
if (n < 3) {
339+
return 1;
340+
}
341+
const a = [
342+
[1, 1, 0],
343+
[1, 0, 1],
344+
[1, 0, 0],
345+
];
346+
return pow(a, n - 3)[0].reduce((a, b) => a + b);
347+
};
348+
349+
function mul(a, b) {
350+
const [m, n] = [a.length, b[0].length];
351+
const c = Array.from({ length: m }, () => Array.from({ length: n }, () => 0));
352+
for (let i = 0; i < m; ++i) {
353+
for (let j = 0; j < n; ++j) {
354+
for (let k = 0; k < b.length; ++k) {
355+
c[i][j] += a[i][k] * b[k][j];
356+
}
357+
}
358+
}
359+
return c;
360+
}
361+
362+
function pow(a, n) {
363+
let res = [[1, 1, 0]];
364+
while (n) {
365+
if (n & 1) {
366+
res = mul(res, a);
367+
}
368+
a = mul(a, a);
369+
n >>= 1;
370+
}
371+
return res;
372+
}
373+
```
374+
375+
### **TypeScript**
376+
377+
```ts
378+
function tribonacci(n: number): number {
379+
if (n === 0) {
380+
return 0;
381+
}
382+
if (n < 3) {
383+
return 1;
384+
}
385+
const a = [
386+
[1, 1, 0],
387+
[1, 0, 1],
388+
[1, 0, 0],
389+
];
390+
return pow(a, n - 3)[0].reduce((a, b) => a + b);
391+
}
392+
393+
function mul(a: number[][], b: number[][]): number[][] {
394+
const [m, n] = [a.length, b[0].length];
395+
const c = Array.from({ length: m }, () => Array.from({ length: n }, () => 0));
396+
for (let i = 0; i < m; ++i) {
397+
for (let j = 0; j < n; ++j) {
398+
for (let k = 0; k < b.length; ++k) {
399+
c[i][j] += a[i][k] * b[k][j];
400+
}
401+
}
402+
}
403+
return c;
404+
}
405+
406+
function pow(a: number[][], n: number): number[][] {
407+
let res = [[1, 1, 0]];
408+
while (n) {
409+
if (n & 1) {
410+
res = mul(res, a);
411+
}
412+
a = mul(a, a);
413+
n >>= 1;
414+
}
415+
return res;
416+
}
417+
```
418+
140419
### **PHP**
141420

142421
```php

0 commit comments

Comments
 (0)