本文介紹了遞迴的原理及其斐波那契數列的四種實現方式。所有原始碼均已上傳至github:鏈結
比較經典的例子就是最知名的斐波那契數列了。本文也以斐波那契數列為例,先簡單介紹一下,斐波那契數列(fibonacci sequence),又稱**分割數列(這個名字高大上)。
指的是這樣乙個數列:1、1、2、3、5、8、13、21、34、……
在數學上,斐波納契數列以如下被以遞推的方法定義:f(1)=1,f(2)=1, f(n)=f(n-1)+f(n-2)(n>=3,n∈n*)在現代物理、準晶體結構、化學等領域,斐波納契數列都有直接的應用。大致就是這樣。
時間複雜度:o(2^n)
空間複雜度:o(n)
這是最簡單的遞迴,只有兩行**,是不是很簡單呢?
public int recursion(int num) 複製**
但是這種實現的缺陷是重複計算的次數太多了,效率極其低下:
f(3) = f(1) + f(2);
f(4) = f(2) + f(3);
f(5) = f(3) + f(4);
f(6) = f(5) + f(6);
當計算到f(6)的時候,f(3)就已經重複了3次,因此改造一下:
public int recursion(int num)
int res = recursion(num - 1) + recursion(num - 2);
rescache.put(num, res);
return res;
}複製**
ps:加乙個hashmap來做快取,避免重複計算
時間複雜度:o(n-2)約等於0(n)
空間複雜度:o(n-2)約等於0(n)(編譯器如果優化的話是o(1))
先簡單了解一下什麼是尾遞迴。
定義:在乙個程式中,執行的最後一條語句是對自己的呼叫,而且沒有別的運算
尾遞迴的實現:是在編譯器優化的條件下實現的
小知識(編譯器優化):
遞迴的第一次呼叫時會開闢乙份空間,此後的遞迴呼叫不會再開闢空間,而是在剛才開闢的空間上做一些修改,實現此次遞迴,例如求f(10),編譯器會給f(10)的呼叫開闢棧幀,呼叫f(9)的時候不會再重新開闢棧幀,而是在剛開闢的棧幀上做一些修改,因為遞迴的每一次呼叫都是一樣的流程,只是會有一些資料不同,所以不會再開闢空間。
public int tailrecursion(int num, int first, int second) 複製**
下面兩種是非遞迴的實現,就比較簡單了,在此不做闡述。
public int commonrcursion(int num)
return res;
}複製**
public int arrayrecursion(int num)
return arrays[num];
}複製**
您的點讚和關注是對我最大的支援,謝謝!
不一樣的雙十一,移動雲走進生活,開啟不一樣的篇章
才開始,一台小巧的諾基亞按鍵機便能讓你開心許久 隨後觸控螢幕手機的問世 彷彿為你開啟新世界的大門 而智慧型手機這一類的高階電子產品的一聲平地驚雷 讓你以為這將是這一行業的巔峰 但是移動雲不一樣 它將讓你見識到什麼叫做精妙絕倫 它將成為 屠龍勇士手中的屠龍利刃 it行業 雲上 的不可缺一 不論是 雲上...
不一樣又不一樣的 木板接水
空地上豎立著n個從左到右排列的木板,它們可以把水擋住,但溢位最邊上木板的水將會流到空地上。已知木板間距都是單位1,現給定每個木板的高度,請求出總共能接住的水量?說明一點,這裡只考慮間距 寬度 和高度,不考慮第三個維度,因此水量是平方單位。木板高度分別是2,1,3,那麼我們可以接住2 2 4平方單位的...
斐波那契數列的
includeint main return 0 似乎是個斐波那契數列的變形。f0 0 f1 1 fn fn 1 fn 2 當然,2012級同學的第一次練習的第乙個題不應該如此複雜,於是我們簡化一下,我們約定fn表示斐波那契數列的第n項 n 50 你能知道斐波那契數中的任何一項嗎?輸入處理到檔案結束...