一般Fibonacci算法的优化

一般的Fibonacci算法:

int Fibonacci(int number)
{
    if (number < 2) return number;
    return Fibonacci(number - 1) + Fibonacci(number - 2);
}

该算法的时间复杂度达到了惊人的指数级别,效率慢的不行,下面提供两种不同的改进方式,时间复杂度分别为O(n)和O(logn)。

方法一:O(n)

int Fibonacci(int number)
{
    if (number < 2) return number;

    int fibonacci[2] = {0, 1};
    int result = 0;
    for (int index = 2; index <= number; ++index) {
        result = fibonacci[0] + fibonacci[1];
        fibonacci[0] = fibonacci[1];
        fibonacci[1] = result;
    }
    return result;
}

将原本的自顶向下计算的方式,改为自底向上,消除原本过多的冗余计算,来降低时间复杂度。

方法二:O(logn)

数据结构:

struct Matrix2By2
{//second order matrix
public:
    Matrix2By2(int m00 = 1, int m01 = 1, int m10 = 0, int m11 = 0)
      :m_00(m00), m_01(m01), m_10(m10), m_11(m11) {}

public:
    int m_00;
    int m_01;
    int m_10;
    int m_11;
};

Matrix2By2 MatrixMultiply(const Matrix2By2& matrix1, const Matrix2By2& matrix2)
{//matrix1 multiply matrix2
    return Matrix2By2(matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10,
                      matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11,
                      matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10,
                      matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11);
}

递归方式:

Matrix2By2 MatrixPower(Matrix2By2 matrix, int exponent)
{//matrix exponentation
      if(1 == exponent) return matrix;

      if(exponent & 1) {
          return MatrixMultiply(MatrixPower(MatrixMultiply(matrix, matrix), exponent >> 1),
                                matrix);
      } else {
          return MatrixPower(MatrixMultiply(matrix, matrix), exponent >> 1);
      }
}

int Fibonacci(int number)
{
    if (number < 2) return number;

    //initialization
    Matrix2By2 matrix = Matrix2By2(1, 1, 1, 0);

    matrix = MatrixPower(matrix, number - 1);

    return matrix.m_00;
}

非递归方式:

int Fibonacci(int number)
{
    if (number < 2) return number;

    //initialization
    Matrix2By2 matrix(1, 1, 1, 0);
    Matrix2By2 result(1, 0, 1, 0);
    int exponent = number - 1;

    while (exponent) {
        if (exponent & 1) {
            --exponent;
            result = MatrixMultiply(result, matrix);
        }
        matrix = MatrixMultiply(matrix, matrix);
        exponent = exponent >> 1;

    }
    return result.m_00;
}

利用了{f(n), f(n-1), f(n-1), f(n-2)} ={1, 1, 1,0}n-1的性质,实际上就是2阶矩阵(a11 = 1, a12 = 1, a21 = 1, a22 = 0)的n-1次幂,fibonacci(n)为该矩阵n-1次幂的a11。

原文地址:https://www.cnblogs.com/wolves-dave/p/3297567.html