斐波那契數列


斐波那契數列如下:

    1,2,3,5,8,13,21,34,……

    如果設F(n)為該數列的第n項(n∈N*),那么這句話可以寫成如下形式:

    F(n)=F(n-1)+F(n-2)

通項公式如下:

    

 

遞歸實現:

    直接按照遞推公式實現,

    由通項公式可以得到:當n趨近於無窮大時

              

    由於T(n)≥F(n),這是一個指數階的算法

    如果我們今年計算出了F(100),那么明年才能算出F(101),

    爆炸增量函數是算法設計的噩夢。

1 int fib(int n)
2 {
3     if( n < 1)
4         return -1;
5     if( n == 1 || n == 2)
6         return 1;
7     return fib( n-1) + fib( n-2);
8 }

 數組優化:

    既然斐波那契數列中的每一項是前兩項之和,如果記錄前兩項的值,只需

    要一次加法運算就可以得到當前項,那么可以使用數組。復雜度為O(n)。

 1 int fib( int n)
 2 {
 3     if( n < 1)
 4         return -1;
 5     int *a = new int [n];
 6     a[1] = a[2] = 1;
 7     for( int i = 3; i <= n; i++)
 8         a[i] = a[i-1]+a[i-2];
 9     return a[n];
10 }

 迭代法:

    其實只需要得到第n個斐波那契數,中間結果只是為了下一次使用,不需要

    記錄,因此可以采用迭代法進行設計。使用若干輔助變量,迭代輾轉相

    加,每次記錄前一項,時間復雜度為O(n),空間復雜度降到O(1)。

 1 int fib( int n)
 2 {
 3     int i, s1, s2;
 4     if( n < 1)
 5         return -1;
 6     if( n == 1 || n == 2)
 7         return 1;
 8     s1 = s2 = 1;
 9     for( i = 3; i <= n; i++)
10     {
11         s2 = s1+s2;
12         s1 = s2-s1;
13     }
14     return s2;
15 }

對數階:

    實質上,斐波那契數列時間復雜度還可以進一步降低到對數階O(logn)。

    我們每次遞歸都將a+b的值賦給a,把a的值賦給b,通過觀察可以發現,從1和

    0開始將規則反復應用n次,將產生一對數fib(n)和fib(n+1),

    現在將這種規則看成a = bq + aq + a*pb = bp + aq,其中p=0,q=1。把這種變

    換稱為T變換,Tpq 變換有個特性是 :

    Tpq 的二次方等於Tp'q', p' = pp + qq'q' = 2pq + q*q。

    即:a = (bp+aq)p+(bq+aq+ap)q+(bq+aq+ap)p

         = b(2pq+q^2)+a(p^2+2pq+2q^2)

      b = (bp+aq)p+(bq+aq+ap)q = b(p^2+q^2)+a(q^2+2pq)
    此處p=0,q=1

 1 int fib_iter( int a, int b, int count)
 2 {
 3     if( count == 0)
 4         return b;
 5     return fib_iter( a+b, a, count-1);
 6 }
 7 int fib( int n)
 8 {
 9     return fib_iter( 1, 0, n);
10 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM