斐波那契数列求解的优化

题目:给定整数N,返回斐波那契数列的第N项。

解法一:暴力递归,时间复杂度为O(2^N)
int fun(int n)
{
    if(n < 1)
    {
        return 0;
    }
    else if(n ==1 || n ==2)
    {
        return 1;
    }

    return fun(n-1) + fun(n-2);
}

解法二:保存前面求出的值,时间复杂度为O(N)

int fun(int n)
{
    if(n < 1)
    {
        return 0;
    }
    else if(n ==1 || n ==2)
    {
        return 1;
    }
    else
    {
        int res1 = 1, res2 = 1;
        int result = 1, i = 0;

        for(i = 3; i <= n; i++)
        {
            result = res1 + res2;

            res1 = res2;
            res2 = result;
        }

        return result;
    }
}

解法三:采用矩阵乘法,把时间复杂度降为O(logN)

 递归优化的通用公式如下:

#include <iostream>
#include <vector>

using namespace std;


/* 矩阵的乘法,m1,m2是两个矩阵,结果为result */
int mulMatrix(vector<vector<int> > m1, vector<vector<int> > m2, vector<vector<int> > &result)
{
    int i = 0, j = 0, k = 0;

    /* 如果不符合矩阵相乘的条件 */
    if (m1.size() != m2[0].size())
    {
        return 1;
    }

    for(i = 0; i < m2[0].size(); i++)//result的行标
    {
        for(j = 0; j < m1.size(); j++)//result的下标
        {
            /* 先把这个地方数值,清零 */
            result[i][j] = 0;
            for(k = 0; k < m2.size(); k++)//每次加的个数
            {
                result[i][j] += m1[i][k] * m2[k][j];
            }
        }
    }

    return 0;
}

/* 求m矩阵的n次方 */
int matrixPower(vector<vector<int> > m, int p, vector<vector<int> > &result)
{
    int i = 0;
    vector<vector<int> > temp = m;
    vector<vector<int> > tempp;

    /* 把result设为单位矩阵,相当于整数中的1 */
    for(i = 0; i < m.size(); i++)
    {
        result[i][i] = 1;
    }

    for(; p != 0; p >>= 1)
    {
        if ((p & 1) != 0 )
        {
            tempp = result;
            mulMatrix(tempp,temp,result);
        }

        tempp = temp;
        mulMatrix(tempp,tempp,temp);
    }

}

/* 求斐波那契数列第N项 */
int fun(int n)
{
    if (n < 1)
    {
        return 0;
    }
    else if (n == 1 || n == 2)
    {
        return 1;
    }

    /* 构建矩阵 */
    vector<vector<int> > base(2);
    base[0].push_back(1);
    base[0].push_back(1);
    base[1].push_back(1);
    base[1].push_back(0);

    vector<vector<int> >res(2);
    res[0].push_back(0);
    res[0].push_back(0);
    res[1].push_back(0);
    res[1].push_back(0);

    matrixPower(base,n-2,res);

    return res[0][0] + res[1][0];
}


int main( void )
{
/*
    vector<vector<int> > m1(2);
    m1[0].push_back(1);
    m1[0].push_back(2);
    m1[1].push_back(1);
    m1[1].push_back(2);


    vector<vector<int> > m3 = m1;
    m3[0][0] = 0;
    m3[0][1] = 0;
    m3[1][0] = 0;
    m3[1][1] = 0;


    matrixPower(m1,3,m3);
    cout << m3[0][0] << " " << m3[0][1] << endl;
    cout << m3[1][0] << " " << m3[1][1] << endl;
*/


    cout << fun(5) << endl;
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dmfrm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值