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

递归法:

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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值