《LeetCode之每日一题》:116.第 N 个泰波那契数
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:116.第 N 个泰波那契数相关的知识,希望对你有一定的参考价值。
题目链接: 第 N 个泰波那契数
有关题目
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下
Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
示例 1:
输入:n = 4
输出:4
解释:
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4
示例 2:
输入:n = 25
输出:1389537
提示:
0 <= n <= 37
答案保证是一个 32 位整数,即 answer <= 2^31 - 1。
题解
法一:递归(超时)
int tribonacci(int n){
if (n == 0) return 0;
else if (n <= 2) return 1;
else if (n == 3) return 2;
else return tribonacci(n - 1) + tribonacci(n - 2) + tribonacci(n - 3);
}
法二:记忆化搜索
参考宫水三叶
int cache[38] = { 0 };
int tribonacci(int n){
if (n == 0) return 0;
else if (n <= 2) return 1;
if (cache[n]) return cache[n];
cache[n] = tribonacci(n - 1) + tribonacci(n - 2) + tribonacci(n - 3);
return cache[n];
}
时间复杂度:O(N)
空间复杂度:O(N)
法三:动态规划
int tribonacci(int n){
int dp[n + 1];
memset(dp, 0, sizeof(dp));
if (n == 0) return 0;
if (n <= 2) return 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];
}
时间复杂度:O(N)
空间复杂度:O(N)
法四:滚动数组
int tribonacci(int n){
int pre = 1, ppre = 1, pppre = 0;
int ans = 0;
if (n == 0) return pppre;
if (n <= 2) return pre;
for (int i = 3; i <= n; i++){
ans = pre + ppre + pppre;
pppre = ppre;
ppre = pre;
pre = ans;
}
return ans;
}
时间复杂度:O(N)
空间复杂度:O(1)
法五:位运算
class Solution {
public:
int tribonacci(int n) {
int dp[4] = {0, 1, 1, 2};
for (int i = 4; i <= n; ++i){
dp[i & 3] = dp[(i+1) & 3] + dp[(i+2) & 3] + dp[(i+3) & 3];
}
return dp[n % 4];
}
};
时间复杂度:O(N)
空间复杂度:O(1)
法六:取模运算
class Solution {
public:
int tribonacci(int n) {
int dp[4] = {0, 1, 1, 2};
for (int i = 4; i <= n; ++i){
dp[i % 4] = dp[(i+1) % 4] + dp[(i+2) % 4] + dp[(i+3) % 4];
}
return dp[n % 4];
}
};
时间复杂度:O(N)
空间复杂度:O(1)
法七:矩阵快速幂
思路:
res[0][2] = res[2][0] + res[2][1] = res * [1,1,0]^T(矩阵转置->列向量)
//C++
class Solution {
public:
int tribonacci(int n) {
if (n == 0) {
return 0;
}
if (n <= 2) {
return 1;
}
//long不会溢出
vector<vector<long>> q = {{1, 1, 1}, {1, 0, 0}, {0, 1, 0}};
vector<vector<long>> res = pow(q, n);
return res[2][0] + res[2][1];
}
vector<vector<long>> pow(vector<vector<long>>& a, long n) {
vector<vector<long>> ret = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
while (n > 0) {
if ((n & 1) == 1) {
ret = multiply(ret, a);
}
n >>= 1;
a = multiply(a, a);
}
return ret;
}
vector<vector<long>> multiply(vector<vector<long>>& a, vector<vector<long>>& b) {
vector<vector<long>> c(3, vector<long>(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;
}
};
//C
struct Matrix {
long mat[3][3];
};
struct Matrix multiply(struct Matrix* a, struct Matrix* b) {
struct Matrix c;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
c.mat[i][j] = a->mat[i][0] * b->mat[0][j] + a->mat[i][1] * b->mat[1][j] + a->mat[i][2] * b->mat[2][j];
}
}
return c;
};
struct Matrix qpow(struct Matrix* a, long n) {
struct Matrix ret = {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}};
while (n > 0) {
if ((n & 1) == 1) {
ret = multiply(&ret, a);
}
n >>= 1;
*a = multiply(a, a);
}
return ret;
}
int tribonacci(int n) {
if (n == 0) {
return 0;
}
if (n <= 2) {
return 1;
}
struct Matrix q = {{{1, 1, 1}, {1, 0, 0}, {0, 1, 0}}};
//c语言结构体传参最好传指针
struct Matrix res = qpow(&q, n);
return res.mat[0][2];
}
时间复杂度:O(log(N))
空间复杂度:O(1)
以上是关于《LeetCode之每日一题》:116.第 N 个泰波那契数的主要内容,如果未能解决你的问题,请参考以下文章