剑指offer-面试题9.斐波拉契数列
题目一:写一个函数,输入n,求斐波拉契数列的第n项。
斐波拉契数列的定义如下:
1 { 0 n=0; 2 f(n)={ 1 n=1; 3 { f(n-1)+f(n-2) n>1;
斐波拉契问题很明显我们会想到用递归来解决:
1 long long Fibonacci(unsigned int n) 2 { 3 if(n==0) 4 return 0; 5 if(n==1) 6 return 1; 7 8 if(n>1) 9 return Fibonacci(n-1)+Fibonacci(n-2); 10 }
这道题用递归解决思路很清晰,代码很简单,那么问题来了
根据马克思辩证主义思想,往往简单的思路会带来较大的
时间空间开销。在这种递归计算的过程中往往会计算很多
重复的项,比如计算f(6)时就需要计算f(5),f(4),计算f(5)时
会计算f(4),f(3)然而f(4)在之前计算f(6)的过程中就已经计算
过了。看似这不会带来很大的开销,但是我们这样想一想
斐波拉契中的每个数的计算都由两个数组成,然而这两个数
中就有一个是已重复计算了,相当于计算时间增加了1倍,效率
降低了一倍。
下面我们用非递归解法来解这道题:
1 #include <iostream> 2 using namespace std; 3 4 long Fibonacci(unsigned int n) 5 { 6 long int answer[2]={0,1}; 7 if(n<2) 8 return answer[n]; 9 10 long int nums2=1; 11 long int nums1=0; 12 long int ans=0; 13 14 for(int i=2;i<=n;i++) 15 { 16 ans=nums2+nums1; 17 nums1=nums2; 18 nums2=ans; 19 } 20 return ans; 21 } 22 23 int main() 24 { 25 unsigned int data; 26 cout<<"Input the n: "; 27 cin>>data; 28 29 cout<<"The answer is: "<<Fibonacci(data)<<endl; 30 return 0; 31 }
运行截图:
当然剑指Offer一书还提到了另外两种方法:
1.由于在计算的时候有重复项,那么我们可以保存计算的中间项,当计算的时候如果找到
已经计算的重复项则不必重复计算
2.另外一种方法是时间复杂度为logn的方法,这种方法具体可以参考剑指offer一书。
作者:vpoet
出处:http://www.cnblogs.com/vpoet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://www.cnblogs.com/vpoet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。