递归法:
最容易想到的一种方法,简单易行,但缺点太明显。
#include<stdio.h>
int fib(int n)
{
if (n == 1 || n == 2)
return 1;
return fib(n-1) + fib(n-2);
}
int main()
{
printf("%d\n", fib(10));
getchar();
return 0;
}
暂不论使用了多少栈空间,算法本身就是指数级的复杂度了。
迭代法:
也是很容易想到的一个方法,开一个数组,依次求解。
#include<stdio.h>
#define maxn 30
int fib[maxn];
int main()
{
fib[1] = fib[2] = 1;
for(int i = 3; i < maxn; i++)
fib[i] = fib[i-1] + fib[i-2];
printf("%d\n", fib[10]);
getchar();
return 0;
}
时间复杂度是O(n), 空间复杂度是O(n).
滚动数组:
既然fib[i]只跟fib[i-1], fib[i-2]有关,从fib[i-3]开始就没用了。那么这些空间完全可以利用起来。
#include<stdio.h>
int fib[3];
int main()
{
fib[0] = fib[1] = 1;
for(int i = 2; i < 10; i++)
fib[i%3] = fib[(i-1)%3] + fib[(i-2)%3];
printf("%d\n", fib[(10-1)%3]);
getchar();
return 0;
}
时间复杂度是O(n), 空间复杂度是O(1)
公式法:
斐波那契本身有通项公式-_-|||,所以一个公式就搞定了,唯一缺点是double的精度有限,有时可能不够精确
#include<stdio.h>
#include<math.h>
int fib(int n)
{
double sq = sqrt(5.0);
return int((pow(1+sq, n) - pow(1-sq, n)) / (pow(2.0, n) * sq));
}
int main()
{
printf("%d\n", fib(10));
getchar();
return 0;
}