Fibonacci
(斐波那契) 数列的几种求法及复杂度分析
斐波那契数列是一个有规律的神奇数列,1,1,2,3,5,8,13,21……
规律就是从第三项开始,每一项的结果为相邻相邻前两项的和,即 Fn = Fn-1 + Fn-2 ,知道这个规律后,相信大家已经有办法得到第n项的值
下面介绍几种方法供大家参考
非递归方法
①
int Fib1(int n) {
int a = 1;
int b = 1;
if (n <= 2) {
cout<<"第"<<n<<"项为:"<<a<<endl;
}
else{
for(int i = 3; i <= n; i++) {
int tmp = b;
b = a + b;
a = tmp;
}
return b;
}
}
此种方法比较简单,一个循环就能解决,时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)
②
int Fib2(int n) {
int F[n+1]; //F[0]不用
F[1] = 1;
F[2] = 1;
for (int i = 3; i <= n; i++) {
F[i] = F[i-1] + F[i - 2];
}
return F[n];
}
此方法需要开辟一个数组,所以时间复杂度为 O ( n ) O(n) O(n),空间复杂度也为 O ( n ) O(n) O(n),优点是从第1项到第n项的数据都可以保存
递归方式
①
int Fib3(int n) {
if (n == 1 || n == 2)
return 1;
else
return Fib3(n - 1) + Fib3(n - 2);
}
函数体超级简单,但此方法时间复杂度为O(2n),空间复杂度 O ( n ) O(n) O(n),这个时间复杂度是非常高的,不建议使用
读者可用递归树的形式证明其时间复杂度
②递归优化
int Fib4(int a, int b, int n) {
if (n <= 2)
return 1;
else if (n == 3)
return a + b;
else
return Fib4(b, a + b, n - 1);
}
这里相当于用a和b来记录当前相加的两个数值,此时就不用两次递归了。每次递归的时候n减1,即只是递归了n次,所以时间复杂度是 O ( n ) O(n) O(n),空间复杂度也为 O ( n ) O(n) O(n)