1、概念
在數學上,費波那契數列是以遞迴的方法來定義:
f0=0
f1=1
fn=fn-1+fn-2(n≧2)
用文字來說,就是費波那契數列由0和1開始,之後的費波那契係數就是由之前的兩數相加而得出。首幾個費波那契係數是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……(oeis中的數列a000045)
特別指出:0不是第一項,而是第零項。
2、解法
2.1遞迴解法
(1)**
/*斐波那契遞迴解法*/
#include #include using namespace std;
long fibonacci(unsigned int n) else
}int main()
else
}long fibonacci(unsigned int n)
unsigned long ret=0;
//申請陣列用於儲存已經計算過的內容
unsigned long *array=(unsigned long*)calloc(n+1, sizeof(unsigned long));
if(array == null)
array[1]=1;
ret=fibonacciprocess(array,n);
free(array);
array=null;
return ret;
}
可見改進版本,時間複雜度為o(n),避免了重複計算,但是呼叫鏈仍然比較長。
2.3 迭代解法
遞迴法不夠優雅。如果不用計算機計算,讓你去算第n個斐波那契數,會怎麼做?最簡單直接的方法是:知道第乙個和第二個,計算第三個;知道第二個和第三個,計算第四個,以此類推。最終可以得到我們需要的結果。這種思路沒有冗餘的計算。**實現如下:
/*斐波那契數迭代解法*/
long fibonacciiterration(unsigned int n)
unsigned int loop=1;
unsigned long returnval=0;
while(loop < n)
return returnval;
}
時間複雜度為o(n)。
2.4 尾遞迴解法
要計算第n個斐波那契數,我們可以先先計算第乙個,第二個,如果未達到n,則繼續遞迴計算,尾遞迴實現**如下:
/*斐波那契數尾遞迴解法*/
long fibonaccitialrecursionprocess(unsigned int n, unsigned long prepreval, unsigned long preval,unsigned long begin) else
}long fibonacci(unsigned int n) else
}
尾遞迴效率並不遜於迭代法。尾遞迴在函式返回之前的最後乙個操作仍然是遞迴呼叫。尾遞迴的好處是,進入下乙個函式之前,已經獲得了當前函式的結果,因此不需要保留當前函式的環境,記憶體占用自然也是比最看是提到的遞迴要小。時間複雜度為o(n)。
2.5 矩陣快速冪解法
這是一種高效的解法,推導過程如下:
如果a為矩陣,等式同樣成立。
假設有矩陣2*2矩陣a,滿足下面的等式:
可以得到矩陣a:
因此也就可以得到下面的矩陣等式:
再進行變換如下:
以此類推,得到:
實際上f(n)就是矩a^(n-1)中的a[0][0],或者是矩a^n中的a[0][1]。
現在的問題就歸結為,如何求a^n,其中a為2*2的矩陣。根據我們最開始的公式,很容易就有思路,**實現如下:
/*矩陣快速冪解法*/
#define max_col 2
#define max_row 2
typedef unsigned long matrixtype;
//計算2*2矩陣乘法,這裡沒有寫成通用形式的矩陣乘法
int matrixdot(matrixtype a[max_row][max_col],matrixtype b[max_row][max_col],matrixtype c[max_row][max_col])
matrixtype fibonacci(int n)
matrixtype result[max_col]=;
matrixtype a[2]=;
while(n > 0)
n /= 2;
matrixdot(a,a,a);
} return result[0][1];
}
該演算法的關鍵部分在於對a^n的計算,它利用了我們開始提到的等式,對奇數和偶數分別處理。假設n為9,初始矩陣為init則計算過程如下:
·9為奇數,則計算init*a,隨後a變為a*a,n變為9/2,即為4
·4為偶數,則結果仍為init*a,隨後a變為(a2)*( a2)=a4,n變為4/2,即2
·2為偶數,則結果仍為init*a,隨後a變為(a4)*( a4)=a8,n變為2/2,即1
·1為奇數,則結果為init*(a^8)*a
可以看到,計算次數類似於二分查詢次數,其時間複雜度為o(logn)。
斐波那契數列的通項公式為:
**實現如下:
/*斐波那契數列通項公式解法*/
long fibonacci(unsigned long n)
return (unsigned long)((pow((1+sqrt(5))/2,n)-pow((1-sqrt(5))/2,n))/sqrt(5));
}
斐波那契數列解法
方法一 常規解法 def demo month 定義變數 a,b分別表示一月和二月的數目 a 0 a為第乙個數值 b 1 b為第二個數值 定義乙個計數器 i 0 while i month 列印每次的數值 print a a,b b,a b i 1 nume demo 3 方法二 函式的遞迴 def...
斐波那契數列的快速解法
求解斐波那契數列,要求時間複雜度為o logn 主要思路是快速冪和矩陣乘法的結合律 利用數學歸納法來證明。快速冪的思想 當n為偶數的時候 an an2 an2 當n為奇數的時候 an a n 1 2 a n 1 2 a那麼fn 的問題就可以換成求矩陣的n次冪了。實現 class solution p...
題目 斐波那契數列。 解法二
程式分析 斐波那契數列 fibonacci sequence 又稱 分割數列,指的是這樣乙個數列 0 1 1 2 3 5 8 13 21 34 數學上的解法是 f0 0 n 0 f1 1 n 1 fn f n 1 f n 2 n 2 我是小白,大神無笑話小弟,只是想記錄下來自己的思路,根據我自己的理...