目录
一、斐波那契数列的定义
二、递归实现
经典例题(杭电2041):
AC代码:
#include <iostream>
using namespace std;
int f[41];
int main(){
int num,m;
cin >> num;
while(num--){
f[1] = 1;
f[2] = 1;
for(int i = 3;i < 41;i++){
f[i] = f[i-1] + f[i-2];
}
cin >> m;
cout << f[m] << endl;
}
return 0;
}
复杂度分析(以 为例):
- 注意计算复杂度规则:关注最高次数项,忽略常数与系数
- 时间复杂度:为二叉树的所有节点个数
- 在本例中,二叉树的高度 为
- 图中共有 个节点,即 ,可以理解为 ,也就是层数为 的满二叉树( )
- 的层数为 层, 则 有 层,所有节点个数为 ,忽略常数与系数,则为
- 时间复杂度为
- 空间复杂度为树的高度:h 即
分析:递归实现的代码简洁易懂,但是需要注意的是,递归由于是函数调用自身,而函数调用是有时间和空间的消耗的,每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而往栈里压入数据和弹出数据都需要时间,因而递归实现的效率不如循环。
三、循环实现
#include<stdio.h>
int main()
{
int a = 0, b = 1, n = 5;
for(int i = 2;i <= n;i++){
int t = b;
b = a + b;
a = t;
}
printf("%d\n", b);
return 0;
}
时间复杂度:O(N),空间复杂度:O(1)。
四、补充
复杂度O符号表示取上界,Ω表示取下界,Θ当且仅当O() = Ω()时成立。
对于下列题目:
Θ(Fn)中的Fn表示时间复杂度与Fn的取值有关,事实上,时间复杂度只与我们求的是第几项有关,而与第几项的取值无关。
常用时间复杂度所耗费的时间从小到大依次是
O(1)< O(logN) < O(N) < O(NlogN) < O(N^2) < O(N^3) < O(2^N) < O(N!) < O(N^N)