zoukankan      html  css  js  c++  java
  • 剑指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一书。

  • 相关阅读:
    【模板】并查集
    排队布局
    list
    js获取宽度
    js获取按键
    sublime 自定义快捷代码
    file
    git add Untracked files
    git branch
    git
  • 原文地址:https://www.cnblogs.com/vpoet/p/4665434.html
Copyright © 2011-2022 走看看