1 Fibonacci 數列的定義
2 Fibonacci 解法
遞歸計算 Fibonacci 數列
int fibonacci(int n){
if(n<=0) return 0;
if(n==1) return 1;
return fibonacci(n-1)+fibonacci(n-2);
}
遞歸由於是函數調用自身,而函數調用是有時間和空間的消耗的:每一次函數調用,都需要在內存棧中分配空間以保存參數、返回地址及臨時變量,而且往棧裏壓入數據和彈出數據都需要時間。
除了效率之外,遞歸還有可能引起更嚴重的問題:調用棧溢出,遞歸每一次函數調用都需要在內存棧中分配空間,而且每一個進程的棧的容量是有限的。當遞歸的層級太多時,就會超出棧的容量,從而導致調用棧溢出
而且上述遞歸計算 Fibonacci 數列是存在大量的重複計算。
循環計算 Finonacci 數列
int fibonacci(int n){
int i;
int result;
int n_1=1;
int n_2=0;
if(n<=0) return 0;
if(n==1) return 1;
for(i=2;i<=n;i++){
result=n_1+n_2;
n_2=n_1;
n_1=result;
}
return result;
}
Fibonacci 數列的應用
一直青蛙一次可以跳上一個臺階,也可以跳上兩個臺階。求青蛙跳上一個 n 個臺階總共有多少種跳法。
1 個臺階時,只有一種跳法
2 個臺階時,存在兩種跳法
3 個臺階時,如果第一跳跳 1 個臺階,那剩下可能性就是 f(2),如果第一跳跳 2 個臺階,那麼剩下的可能性就是 f(1)
n 個臺階時,f(n)=f(n-1)+f(n-2)
矩形覆蓋
有左邊的小矩形去覆蓋右邊的大矩形,總共有多少種方法?
先把 2*8 的覆蓋方法記爲 f(8),用第一個小矩形去覆蓋最左邊的時有兩個選擇,豎着放和橫着放。當豎着放的時候,右邊還剩下 2*7的區域記爲 f(7),接下來考慮橫着放的情況,當 1 *2 的小矩形橫着放在左上角的時候,左下角也必須橫着放一個 1*2 的小矩形,而在右邊還剩下 2*6 的區域,這種情況記爲 f(6),因此 f(8)=f(7)+f(6),即 Fibnacci 數列的一種應用。