很令人惊讶,Fibonacci数列竟然可以用对数时间复杂度完成。
一下是三个版本的求解:
第一个是最原始的,指数时间复杂度。
第二个是线性记忆的,线性时间复杂度。
第三个是用矩阵记忆的,对数时间复杂度!
/*
Three versions of Fibonacci Number Computation
Nan Wang
University of Queensland
*/
#include <iostream>
using namespace std;
/* O(2^n) */
unsigned int getFib1(const unsigned int);
/* O(n) */
unsigned int getFib2(const unsigned int);
/* O(log n) */
unsigned int getFib3(const unsigned int);
void getFibPair(unsigned int *, const unsigned int);
void main()
{
for (int i = 0; i < 30; i++)
{
cout << getFib1(i) << " ";
}
for (int i = 0; i < 30; i++)
{
cout << getFib2(i) << " ";
}
for (int i = 0; i < 30; i++)
{
cout << getFib3(i) << " ";
}
}
unsigned int getFib1(const unsigned int n)
{
if (n < 2) return n;
return (getFib1(n - 1) + getFib1(n - 2));
}
unsigned int getFib2(const unsigned int n)
{
if (n < 2) return n;
unsigned int f[] = {0, 1};
for (int i = 2; i < n; i++)
{
f[i & 1] = f[0] + f[1];
}
return (f[0] + f[1]);
}
unsigned int getFib3(const unsigned int n)
{
if (n < 2) return n;
unsigned int p[2] = {0, 1};
getFibPair(p, n);
return p[1];
}
void getFibPair(unsigned int * p, const unsigned int n)
{
if (n == 1) return;
getFibPair(p, n >> 1);
int a = p[0] * p[0] + p[1] * p[1];
int b = p[1] * (p[1] + (p[0] << 1));
if (n & 1)
{
p[0] = b;
p[1] = a + b;
}
else
{
p[0] = a;
p[1] = b;
}
}