先看下百度百科對斐波拉契數列的定義:
斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列以如下被以遞歸的方法定義:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 反正就是一句話:斐波拉契牛逼。
第一種數組實現方法:基於數組實現
/** * @author 薛定諤的貓 * 斐波拉契數列數組實現 * 求前二十項*/ public class Main { public static void main(String[] args) { getFib(20); } public static int getFib(int n){//核心函數 if (n<0) { return -1;//小於0是沒有意義的 }else if (n == 0) { return 0;//等於0其實也沒什么意義 }else if (n == 1||n == 2) { return 1;//第一項和第二項都是1 }else { int[] fibAry = new int[n + 1]; fibAry[0] = 0; fibAry[1] = fibAry[2] = 1; for(int i = 3;i<=n;i++) { fibAry[i] = fibAry[i-1] + fibAry[i-2];//當前項等於后一項加上后兩項 System.out.println("第" + i + "項"+fibAry[i]);//輸出當前項 } return fibAry[n];//返回當前項 } } }
第二種實現方法:基於變量實現
/** * @author 薛定諤的貓 * 斐波拉契數列變量實現 * 求前二十項*/ public class Main { public static void main(String[] args) { getFib(20); } public static int getFib(int n){//核心函數 if (n<0) { return -1;//小於0是沒有意義的 }else if (n == 0) { return 0;//等於0其實也沒什么意義 }else if (n == 1||n == 2) { return 1;//第一項和第二項都是1 }else { int temp = 0;//當前項變量 int a = 1;//第一項 int b = 1;//第二項 for(int i = 3;i<=n;i++) { //變量互換值 temp = a+b;//當前項等於前兩項相加 a = b;//前兩項互換值 b = temp;//當前項賦值給前一項 System.out.println("第" + i + "項"+temp);//輸出當前項 } return temp;//返回當前項 } } }
第三種實現方法:遞歸實現(用遞歸的都是神)
遞歸定義:簡單的說就是自己調用自己。
/** * @author 薛定諤的貓 * 斐波拉契數列變量實現 * 求前二十項 * 這種方法最簡單,但是最占用內存,特別是當n很大的時候 * * * 為什么遞歸得效率低? * 遞歸效率低是函數調用的開銷導致的。在一個函數調用之前需要做許多工作, * 比如准備函數內局部變量使用的空間、搞定函數的參數等等,這些事情每次調用函數都需要做 * ,因此會產生額外開銷導致遞歸效率偏低,所以邏輯上開銷一致時遞歸的額外開銷會多一些當然了, * 通過有意識的組織代碼的寫法可以把某些遞歸寫成尾遞歸,尾遞歸可以進行特殊的優化所以效率 * 會比普通的遞歸高一些,也不會因為遞歸太多導致棧溢出遍歷樹還不用遞歸的話,那么人肉寫一個棧 * +深度優先遍歷或者人肉隊列+廣度優先遍歷,再輔以黑魔法給棧或者隊列提速,應該會比遞歸快一些, * 加速幅度和語言和寫法相關,但在大多數情況下我覺得是得不償失的,花了很大精力很可能效率提升不 * 明顯 * * 此回答轉自知乎 * */ public class Main { public static void main(String[] args) { for(int i = 1;i<=20;i++) { System.out.println("第" +i + "項" + getFib(i)); } } public static int getFib(int n){//核心函數 if (n<0) { return -1;//小於0是沒有意義的 }else if (n == 0) { return 0;//等於0其實也沒什么意義 }else if (n == 1||n == 2) { return 1;//第一項和第二項都是1 }else { return getFib(n-1) + getFib(n-2);//返回當前項,核心遞歸 } } }
最后說一句,斐波拉契牛逼。