您的位置:首页 > 其它

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

2014-08-19 00:28 316 查看

递归法:

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

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐