斐波那契数列算法小结

  关于求解斐波那契数列,这是一道比较经典的题目,本文主要是对斐波那契数列求解方法的小结。

首先,定义Fibonacci数列如下:

方法1:

  利用递归求解,这是最容易写出的算法,代码如下:

#include<iostream>
using namespace std;

long Fibonacci(int n)
{
    if (n == 0)
        return 0;
    else if (n == 1)
        return 1;
    else
        return Fibonacci(n - 1) + Fibonacci(n-2);
}

int main()
{
    int N;
    cin >> N;
    cout << Fibonacci(N) << endl;
    return 0;
}

该算法的时间复杂度为O(2^N)。为什么呢?因为每一次计算Fibonacci(n)时,都需要计算Fibonacci(n-1)和Fibonacci(n-2)共2次,相当于计算了n个2相乘的次数。

方法2:

  不用递归,利用迭代的方法计算(理论上讲,任何递归方法都能利用迭代方法实现),代码如下:

#include<iostream>
using namespace std;

long Fibonacci(int n)
{
    if (n == 0)
        return 0;
    else if (n == 1)
        return 1;
    int num1 = 0;//表示F(n-2)
    int num2 = 1;//表示F(n-1)
    for(int i = 1; i < n; i++)
    {
        num2 = num1 + num2;
        num1 = num2 - num1;
    }
    return num2;
}

int main()
{
    int N;
    cin >> N;
    cout << Fibonacci(N) << endl;
    return 0;
}

迭代算法的时间复杂度为O(N),此处应注意一点,这段代码中只用了两个变量num1和num2来分别代替f(n-2)和f(n-1)。实际上也可以用一个数组来代替整个斐波那契数列,只不过空间复杂度会增加。

方法3:

  利用矩阵乘法的原理,斐波那契的递推公式可以表示成如下矩阵形式,所以

      

求Fibonacci(n)就可以转化成求矩阵A的n-1次幂问题了。而对于矩阵幂的问题,我们有:

利用分治的算法思想可以考虑如下求解一个数A的幂。

从它的求解过程来看,这种算法的时间复杂度为O(logN),要比前两种效率都要好,尤其是在N比较大的时候更能体现出这种优势。该算法的实现需要事先定义矩阵以及矩阵相关的计算,代码如下:

#include<iostream>
#include<string>
using namespace std;

//定义2×2矩阵;
struct Matrix2by2
{
    //构造函数
    Matrix2by2
    (
        long m_00,
        long m_01,
        long m_10,
        long m_11
    )
    :m00(m_00),m01(m_01),m10(m_10),m11(m_11)
    {
    }

    //数据成员
    long m00;
    long m01;
    long m10;
    long m11;
};

//定义2×2矩阵的乘法运算
Matrix2by2 MatrixMultiply(const Matrix2by2& matrix1,const Matrix2by2& matrix2)
{
    Matrix2by2 matrix12(1,1,1,0);
    matrix12.m00 = matrix1.m00 * matrix2.m00 + matrix1.m01 * matrix2.m10;
    matrix12.m01 = matrix1.m00 * matrix2.m01 + matrix1.m01 * matrix2.m11;
    matrix12.m10 = matrix1.m10 * matrix2.m00 + matrix1.m11 * matrix2.m10;
    matrix12.m11 = matrix1.m10 * matrix2.m01 + matrix1.m11 * matrix2.m11;
    return matrix12;

}


//定义2×2矩阵的幂运算
Matrix2by2 MatrixPower(unsigned int n)
{
    Matrix2by2 matrix(1,1,1,0);
    if(n == 1)
    {
        matrix = Matrix2by2(1,1,1,0);
    }
    else if(n % 2 == 0)
    {
        matrix = MatrixPower(n / 2);
        matrix = MatrixMultiply(matrix, matrix);
    }
    else if(n % 2 == 1)
    {
        matrix = MatrixPower((n-1) / 2);
        matrix = MatrixMultiply(matrix, matrix);
        matrix = MatrixMultiply(matrix, Matrix2by2(1,1,1,0));
    }
    return matrix;
}
//计算Fibnacci的第n项
long Fibonacci(unsigned int n)
{
    if(n == 0)
        return 0;
    if(n == 1)
        return 1;

    Matrix2by2 fibMatrix = MatrixPower(n-1);
    return fibMatrix.m00;

}

int main()
{
    unsigned int number;
    cin>>number;
    cout<<Fibonacci(number)<<endl;
    return 0;
}

  

参考:

  1.http://blog.csdn.net/liyuanbhu/article/details/51703018

  2.http://www.cnblogs.com/python27/archive/2011/11/25/2261980.html

转载于:https://www.cnblogs.com/wangkundentisy/p/8502751.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值