这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
leetcode-1137-第N个泰波那契数
[博客链接]
[题目描述]
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
示例 1:
输入:n = 4
输出:4
解释:
0,1,1,2,3,5
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4
T_5 =
示例 2:
输入:n = 25
输出:1389537
提示:
-
0 <= n <= 37
-
答案保证是一个 32 位整数,即 answer <= 。
Related Topics
- 记忆化搜索
- 数学
- 动态规划
- 👍 85 👎 0
[题目链接]
[github地址]
[思路介绍]
思路一:循环+非压缩数组
- 本题和斐波那契数列很相似
- 都是通过前几个数的状态找到最后一个数
- 通过定义三个特殊情况判定,然后返回即可
- 这种情况会TLE
public int tribonacci(int n) {
if (n < 1) {
return 0;
}
if (n == 1) {
return 1;
}
if (n == 2){
return 1;
}
if (n == 3) {
return 2;
}
return tribonacci(n-1) + tribonacci(n-2) +tribonacci(n-3);
}
- 时间复杂度O(n)
- 空间复杂度O(n)
思路二:思路一的优化
- 根据斐波那契数列的优化思路很容易想到
- 当前求值只和前三个数有关
- 所以可以直接定义三个变量
- 循环迭代
public int tribonacci(int n) {
if (n < 1) {
return 0;
}
if (n == 1) {
return 1;
}
if (n == 2) {
return 1;
}
int a = 0, b = 1, c = 1;
int res = 2;
for (int i = 3; i <= n; i++) {
res = a + b + c;
a = b;
b = c;
c = res;
}
return res;
}
- 时间复杂度O(n)
- 空间复杂度O(1)
思路三:组合数学
- 没错,这就是与数学有关的简单题
- 大佬们总能找到各种各样的数学公式、数学逻辑
- 这道题就可以使用线性代数里的矩阵来计算
- 公式是墨鳌大佬的贡献
- 其实吧这个矩阵的计算逻辑还是很容易求解的,问题是我想不到矩阵
- 最后得出的矩阵的第一行即
- []
- []
class Matrix {
int[][] a = new int[3][3];
Matrix(boolean x) {
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
a[i][j] = x ? i == j ? 1 : 0 : 0;
}
}
}
}
//乘法运算
Matrix multi(Matrix b) {
Matrix C = new Matrix(false);
for (int k = 0; k < 3; k++) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
C.a[i][j] = (C.a[i][j] + a[i][k] * b.a[k][j]);
}
}
}
return C;
}
//交并运算
Matrix babel(int n) {
Matrix C = new Matrix(true);
Matrix A = new Matrix(false);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
A.a[i][j] = a[i][j];
}
}
for (; n > 0; n >>= 1, A = A.multi(A)) {
if ((n & 1) == 1) {
C = C.multi(A);
}
}
return C;
}
}
public int tribonacci(int n) {
Matrix A = new Matrix(false);
A.a[0][1]=1;
A.a[0][2]=1;
Matrix B = new Matrix(false);
B.a[0][2]=1;
B.a[1][0]=B.a[1][2]=1;
B.a[2][1]=B.a[2][2]=1;
B=(B.babel(n));
A=A.multi(B);
return A.a[0][0];
}
- 时间复杂度O(lgn)
- 空间复杂度O(1)
思路死:玄学数学
- 这个公式也是墨鳌大佬查到的
- 这帮数学家是真厉害啊。
public int tribonacci(int n) {
return (int)Math.floor((Math.pow(33.0*(99.0-17.0*Math.sqrt(33.0)),1.0/3.0)+Math.pow(33.0*(99.0+17.0*Math.sqrt(33.0)),1.0/3.0))/66.0*Math.pow((1.0+Math.pow(19.0-3.0*Math.sqrt(33.0),1.0/3.0)+Math.pow(19.0+3.0*Math.sqrt(33.0),1.0/3.0))/3.0,1.0*n)+0.5);
}
-
时间复杂度O(1)
-
空间复杂度O(1)
-
ToDo:今天白天要出门,先写到这里,还有dp起始也可以用,不过和之前的滚动数组差距不大,晚上回来补,顺便把周赛的补了