第N个泰波那契数——每日一题第三天

先看题目:
泰波那契序列 Tn 定义如下:

T(0) = 0, T(1) = 1, T(2) = 1, 且在 n >= 0 的条件下 T(n+3) = T(n) + T(n+1) + T(n+2)

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

示例 1: 输入:n = 4 输出:4 解释: T_3 = 0 + 1 + 1 = 2 T_4 = 1 + 1 + 2 = 4

示例 2: 输入:n = 25 输出:1389537

来源:力扣网
这是泰波那契数列,不是斐波拉契,虽然差不多哈哈哈。
一看题目,昂,简简单单的递归嘛,
愉快的周末从简单的题开始!
算法逻辑就不写了,简单

class Solution {
private:
    int sum = 0;
public:
    int tribonacci(int n) {
        switch(n)
        {
        case 0:
            return 0;
            break;
        case 1:
            return 1;
            break;
        case 2:
            return 1;
            break;
        }
        return tribonacci(n-1)+tribonacci(n-2)+tribonacci(n-3);
    }
};

兴高采烈去提交,嗷,超时了,不过也在预料之中,
时间复杂度:O(3 ^ n) 类似于三叉树的节点数。
空间复杂度:O(n),栈的深度。
指数级别的时间消耗,恐怖。

再看,超时原因很简单,我们多次计算了重复的数据,例如计算第8个数,那我就得计算T(8)=T(5)+T(6)+T(7),然鹅在计算T(7)的时候,T(5)和T(6)又得计算一次,想象一下,算一个二位数,那么计算量是巨大的。
所以我们要用记忆化搜索,把计算出来的数据存储下来,遇见的时候直接拿来用就行
代码:

class Solution {
private:
    int sum = 0;
public:
    int tribonacci(int n) {
        vector<int> sum(n+10);
        sum[0] = 0;
        sum[1] = 1;
        sum[2] = 1;
        for(int i = 3;i <= n;i++)
        {
            sum[i] = sum[i-1] + sum[i-2] + sum[i-3];
        }
        return sum[n];
        }
};

这下就能顺利通过测试了,不过再看,这里需要一个比n大的字典来记录数据,那相应的内存消耗也会随之n的变大而变大。
看我们已经写出来的两组代码,递归和循环,共同点是什么??
是循环,递归本质也是循环,既然问题在循环这,那我们就看看循环还能不能优化,在公式中,实际上只涉及到四个数的变换,n,n+1,n+2,n+3,循环和递归都是基于这四个数进行的。
既然这样,那我们就动态规划!
代码:

class Solution {
public:
    int tribonacci(int n) {
        int sum[4] = {0};
        sum[0] = 0;
        sum[1] = 1;
        sum[2] = 1;
        for(int i = 3;i <= n;i++)
        {
            sum[3] = sum[0] + sum[1] + sum[2];
            sum[0] = sum[1];
            sum[1] = sum[2];
            sum[2] = sum[3];
        }
        switch(n)
        {
            case 0:
            return 0;
            case 1:
            return 1;
            case 2:
            return 1;
            default:
            return sum[3];
        }
    }
};//更简洁的代码,原理一样
class Solution {
public:
    int tribonacci(int n) {
        long long a = 0,b = 1,c = 1;
        while(n--)
        {
            long long d = a+b+c;
            a = b;
            b = c;
            c = d;
        }
        return a;
    }
};

这里我们只用了四个位置的内存,大大节省了空间
时间复杂度:O(n)
空间复杂度:O(1)
还有一种解法:矩阵快速幂
这种解法效率也很高,我还没看懂,但是文章得发了,花了一早上了,有兴趣的去看LeetCode第1137题。

我是Pico。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值