Fibonacci数列的数学表达式就是:
F(n) = F(n-1) + F(n-2)
F(1) = 1
F(2) = 1
第一种:递归实现,时间复杂度差不多是5n^2/3。
//递归实现
int Fib1(int n)
{
if(n<=2) return 1;
return Fib1(n-1)+Fib1(n-2);
}
第二种:递推实现,时间复杂度是O(n)。
int Fib2(int n)
{
if(n<=2) return 1;
int a1=1,a2=1,a3=1;
for(int i=0;i<n-2;i++)
{
a3=a1+a2;
a1=a2;
a2=a3;
}
return a3;
}
第三种:分而治之实现,时间复杂度是O(lgn)。
我们将数列写成:Fibonacci[0] = 0,Fibonacci[1] = 1Fibonacci[n] = Fibonacci[n-1] + Fibonacci[n-2] (n >= 2)
可以将它写成矩阵乘法形式:
将右边连续的展开就得到:
下面就是要用O(log(n))的算法计算:Fibonacci[n] =
class Matrix
{
public:
long matr[2][2];
Matrix(const Matrix&rhs);
Matrix(long a, long b, long c, long d);
Matrix& operator=(const Matrix&);
friend Matrix operator*(const Matrix& lhs, const Matrix& rhs)
{
Matrix ret(0,0,0,0);
ret.matr[0][0] = lhs.matr[0][0]*rhs.matr[0][0] + lhs.matr[0][1]*rhs.matr[1][0];
ret.matr[0][1] = lhs.matr[0][0]*rhs.matr[0][1] + lhs.matr[0][1]*rhs.matr[1][1];
ret.matr[1][0] = lhs.matr[1][0]*rhs.matr[0][0] + lhs.matr[1][1]*rhs.matr[1][0];
ret.matr[1][1] = lhs.matr[1][0]*rhs.matr[0][1] + lhs.matr[1][1]*rhs.matr[1][1];
return ret;
}
};
Matrix::Matrix(long a, long b, long c, long d)
{
this->matr[0][0] = a;
this->matr[0][1] = b;
this->matr[1][0] = c;
this->matr[1][1] = d;
}
Matrix::Matrix(const Matrix &rhs)
{
this->matr[0][0] = rhs.matr[0][0];
this->matr[0][1] = rhs.matr[0][1];
this->matr[1][0] = rhs.matr[1][0];
this->matr[1][1] = rhs.matr[1][1];
}
Matrix& Matrix::operator =(const Matrix &rhs)
{
this->matr[0][0] = rhs.matr[0][0];
this->matr[0][1] = rhs.matr[0][1];
this->matr[1][0] = rhs.matr[1][0];
this->matr[1][1] = rhs.matr[1][1];
return *this;
}
Matrix power(const Matrix& m, int n)
{
if (n == 1)
return m;
if (n%2 == 0)
return power(m*m, n/2);
else
return power(m*m, n/2) * m;
}
long fib3(int n)
{
Matrix matrix0(1, 1, 1, 0);
matrix0 = power(matrix0, n-1);
return matrix0.matr[0][0];
}
第四种:公式解法,时间复杂度为O(1)。
//公式实现
int Fib4(int n)
{
double gh5=sqrt((double)5);
return (pow((1+gh5),n)-pow((1-gh5),n))/(pow((double)2,n)*gh5);
}