一般的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。