[网易2012年某笔试题] 求斐波那契数列, 要求时间复杂度尽可能小(简单题,不熟悉斐波那契的同学可参考)

来源:互联网 发布:pureVPN软件 编辑:程序博客网 时间:2024/05/29 08:32

递归法:

最容易想到的一种方法,简单易行,但缺点太明显。

#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 30int 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;}

1 0
原创粉丝点击