@@ -52,6 +52,32 @@ T_4 = 1 + 1 + 2 = 4
52
52
53
53
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为给定的整数。
54
54
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
+
55
81
<!-- tabs:start -->
56
82
57
83
### ** Python3**
@@ -67,6 +93,35 @@ class Solution:
67
93
return a
68
94
```
69
95
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
+
70
125
### ** Java**
71
126
72
127
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -86,6 +141,51 @@ class Solution {
86
141
}
87
142
```
88
143
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
+
89
189
### ** C++**
90
190
91
191
``` cpp
@@ -104,6 +204,50 @@ public:
104
204
};
105
205
```
106
206
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
+
107
251
### ** Go**
108
252
109
253
``` go
@@ -116,6 +260,51 @@ func tribonacci(n int) int {
116
260
}
117
261
```
118
262
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
+
119
308
### ** JavaScript**
120
309
121
310
``` js
@@ -137,6 +326,96 @@ var tribonacci = function (n) {
137
326
};
138
327
```
139
328
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
+
140
419
### ** PHP**
141
420
142
421
``` php
0 commit comments