Fibonacci數

斐波那契數列(Fibonacci Sequence)

又稱黃金分割數列,或兔子數列(由於是斐波那契觀察兔子生殖而總結獲得)。面試

在數學上,被定義爲遞推式:F(1)=1, F(2)=1, F(3)=2, F(4)=3, F(5)=5, ..., F(n)=F(n-1)+F(n-2)(n≥3)算法


 單元測試

#include <stdio.h>
#include <time.h>

int R[1000]={0};

int main(void){
    int N = 50;
//    int N = 1e6;
    double start, finish;
    
    start = clock();
    printf("%lld\n", fib(N));
    finish = clock();
    
    printf("%f s", (finish-start)/CLOCKS_PER_SEC);
    
    return 0;
} 

遞歸實現

根據它的遞推表達式,很容易想到使用遞歸實現。單元測試

版本A:

1 int fib_A(int N){
2     if( N <= 2 )
3       return 1;
4     int tmp = fib_A(N-1)+fib_A(N-2);
5     printf("%d: %d\n", N, tmp);
6     return tmp;
7 }

代碼很簡單,可是計算很慢!算前50個Fibonacci數須要超過60秒。分析算法,發現不少實例在進行重複計算!學習

如此,根據這一點很容易想到使用查表的形式進行改進。測試

版本B:

 1 long long fib_B(int N, long long* A){
 2     if( A[N] != 0 )//A已初始化爲0
 3       return A[N];
 4       
 5     A[N] = fib_B(N-1, A)+fib_B(N-2, A);
 6     if( R[N] == 0 ){
 7         printf("%d: %lld\n", N, A[N]);
 8         R[N] = 1;
 9     } 
10     return A[N];
11 }

從結果看,僅算前50個改進明顯,事實測試中算前10000個數壓力都不大(不超過1s)。能夠證實獲得比較好的改進。spa


迭代

遞歸是一種自上而下的算法思路,所以爲了計算n,會保留n(壓棧)去結算n-1,以此類推,直到碰到遞歸基,佔內存較大(O(n))。而迭代是自下而上,若是能獲得迭表明達式,計算應該是很是快且不佔空間的(O(1))。3d

Fibonacci遞推式:F(n)=F(n-1)+F(n-2)。可知當前F(n)的結果須要根據前兩項獲得,所以咱們可使用兩個變量,一直保存前兩項的值,每次迭代都更新這兩項,一直跌到到須要計算的n。code

 1 long long fib_itera(int N){
 2     int i; 
 3     long long f, g;
 4     
 5     f = 1; g = 1;//第1項、第2項的值
 6     for( i=3; i<=N; i++){
 7         f = f + g;
 8         g = f - g;
 9         printf("%d: %lld\n", i, f);
10     } 
11     return f;
12 } 

運行速度是跟以前的遞歸B版本差很少。blog


Fibonacci數應用

Fibonacci數不單單只是在學習遞歸的時候能夠用到,實際中應該是很普遍的。這裏舉兩個例子。遞歸

1. Fibonacci查找

是對二分查找的longN的常係數進行改進,能夠經過嚴格的證實,使用Fibonacci黃金分割在查找時對數列進行分割會獲得最優的常係數。具體實現與證實與在查找篇給出,這裏暫不提。

2. 爬樓梯

也是比較常見的一種面試題:若是每次爬樓梯只能一次跨一個或兩個臺階,那麼到第n個臺階有多少中走法?語義規定地面算第0個臺階。

第一層臺階:F(1) = 1; 第二層臺階:能夠一步一步,也能夠一次兩步,F(2) = 2;第三層臺階:能夠一、一、1,或一、2,或二、1,F(3) = 3;第四層:一、一、一、1,或一、一、2,或一、二、1,或二、一、1,或二、2,F(4) = 5。

獲得遞推式,F(1) = 1,F(2) = 2,F(n) = F(n-1) + F(n-2)(n>2)。

同理,若是一次能夠跨一、二、3個臺階,也同樣能夠先推理出前幾項的值,而後獲得遞推表達式(變形的Fibonacci數列)。

相關文章
相關標籤/搜索