斐波那契数列的时间复杂度详释与改进方法

二阶常系数线性差分方程

齐次差分方程

二阶常系数线性差分方程的一般形式为:
yn+2+ayn+1+byn=f(n)n=012....(11)
abb0f(n)
(11)
yn+2+ayn+1+byn=0................................(12)
yn=λn(12)λ
λn(λ2+aλ+b)=0
λ0yn=λn(12)λ
λ2+aλ+b=0............................................(13)
方程(1-3)成为方程(1-1)或(1-2)的特征方程,特征方程的解称为特征根或特征值。
根据二次代数方程(1-3)解的三种情况,可以仿照二阶常系数齐次线性微分方程,分别给出方程(1-1)的通解。
1.1特征方程有两个相异实根
Δ=a24b>0(12)
λ1=12(aΔ)λ2=12(a+Δ)....(14)
于是方程(1-2)有两个特解
yn1=λn1yn2=λn2
yn1yn2=(λ1λ2)nyn1yn2线(12)
yn=C1λn1+C2λn2λ1λ2(14)C1C2
1.2特征方程有二重根
Δ=a24b=0(13)λ1=λ2=12a(12)yn1=(12a)n(12)yn2=n(12a)n
(注:系数n可参照二阶常系数线性齐次微分方程的通项证明求得)
yn1yn2=1nyn1yn2线(102)
yn=(C1+C2n)(12a)nC1C2
1.3特征方程有两个共轭复根
Δ=a24b<0(13)
λ1=12(a+iΔ)λ2=12(aiΔ)
通过直接验证可知,方程(1-2)有两个特解
yn1=rncosβnyn2=rnsinβn
r=(a2)2+(Δ2)2=b........()

斐波那契数列的递推式及通项公式

yn+2=0,1,yn+1+yn,n=0n=1..(15)n>1
(12)yn+2yn+1yn=0............(16)
其中a=-1,b=-1
yn=λn(16)λn(λ2λ1)=0
yn=C1(1+52)n+C2(152)ny0=0y1=1
C1=15C2=15
yn=15(1+52)n15(152)n
可知,时间复杂度为指数形式。

改进方法:

1.时间复杂度为O(n)的方法:

    int Fibonacci(int n) {
        if (n<=0) {
            return 0;
        }
        if (n==1) {
            return 1;
        }
        int min=0;
        int max=1;
        int i=2;
        int result=0;
        while (i<=n) {
            result=min+max;
            min=max;
            max=result;
            ++i;
        }
        return result;

2.时间复杂度为O(logn)的方法:
根据式(1-5),可以化成矩阵的形式:
(yn+2yn+1)=(1110)(yn+1yn)==(1110)n+1(y1y0)
yn(n+1)(n2)/2O(logn)

#include <iostream>
using namespace std;

class Matrix
{
public:
    int n;
    int **m;
    Matrix(int num)
    {
        m=new int*[num];
        for (int i=0; i<num; i++) {
            m[i]=new int[num];
        }
        n=num;
        clear();
    }
    void clear()
    {
        for (int i=0; i<n; ++i) {
            for (int j=0; j<n; ++j) {
                m[i][j]=0;
            }
        }
    }
    void unit()
    {
        clear();
        for (int i=0; i<n; ++i) {
            m[i][i]=1;
        }
    }
    Matrix operator=(const Matrix mtx)
    {
        Matrix(mtx.n);
        for (int i=0; i<mtx.n; ++i) {
            for (int j=0; j<mtx.n; ++j) {
                m[i][j]=mtx.m[i][j];
            }
        }
        return *this;
    }
    Matrix operator*(const Matrix &mtx)
    {
        Matrix result(mtx.n);
        result.clear();
        for (int i=0; i<mtx.n; ++i) {
            for (int j=0; j<mtx.n; ++j) {
                for (int k=0; k<mtx.n; ++k) {
                    result.m[i][j]+=m[i][k]*mtx.m[k][j];
                }   
            }
        }
        return result;
    }
};
int main(int argc, const char * argv[]) {
    unsigned int num=2;
    Matrix first(num);
    first.m[0][0]=1;
    first.m[0][1]=1;
    first.m[1][0]=1;
    first.m[1][1]=0;
    int t;
    cin>>t;
    Matrix result(num);
    result.unit();
    int n=t-2;
    while (n) {
        if (n%2) {
            result=result*first;
            }
        first=first*first;
        n=n/2;
    }
    cout<<(result.m[0][0]+result.m[0][1])<<endl;
    return 0;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值