本文介紹了遞歸的原理及其斐波那契數列的四種實現方式。
全部源碼均已上傳至github:連接git
比較經典的例子就是最知名的斐波那契數列了。本文也以斐波那契數列爲例,先簡單介紹一下,斐波那契數列(Fibonacci sequence),又稱黃金分割數列(這個名字高大上)。程序員
指的是這樣一個數列:一、一、二、三、五、八、1三、2一、3四、……
github
在數學上,斐波納契數列以以下被以遞推的方法定義:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在現代物理、準晶體結構、化學等領域,斐波納契數列都有直接的應用。大體就是這樣。
算法
這是最簡單的遞歸,只有兩行代碼,是否是很簡單呢?數組
public int recursion(int num) {
if (num < 3) return 1;
return recursion(num - 1) + recursion(num - 2);
}複製代碼
可是這種實現的缺陷是重複計算的次數太多了,效率極其低下:緩存
F(3) = F(1) + F(2);bash
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) {
// 必定要先給出遞歸跳出條件
if (num < 3)
return 1;
// resCache是一個HashMap,key是num,value是res
if (resCache.containsKey(num)) {
return resCache.get(num);
}
int res = recursion(num - 1) + recursion(num - 2);
resCache.put(num, res);
return res;
}複製代碼
ps:加一個hashMap來作緩存,避免重複計算
先簡單瞭解一下什麼是尾遞歸。
小知識(編譯器優化):
public int tailRecursion(int num, int first, int second) {
if (num < 3)
return 1;
if (num == 3)
return first + second;
return tailRecursion(num - 1, second, first + second);
}複製代碼
下面兩種是非遞歸的實現,就比較簡單了,在此不作闡述。
public int commonRcursion(int num) {
if(num < 3) return 1;
int first = 1;
int second = 1;
int res = 0;
for (int i = 1; i < num - 1; i++) {
res = first + second;
first = second;
second = res;
}
return res;
}複製代碼
public int arrayRecursion(int num) {
if(num < 3) return 1;
int[] arrays = new int[num + 1];
arrays[1] = 1;
arrays[2] = 1;
for (int i = 3; i <= num; i++) {
arrays[i] = arrays[i - 1] + arrays[i - 2];
}
return arrays[num];
}複製代碼
下一篇則分享程序員必會的五個排序。
您的點贊和關注是對我最大的支持,謝謝!