問題:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
看到這個就想起了上學的時光,那個苦啊.
廢話不多說,當時看到這個問題我就想到了遞歸,然后匆匆寫了代碼如下:
1 public static int fn(int n) { 2 3 if(n == 1) { 4 return 1; 5 } else if(n == 2) { 6 return 2; 7 } else { 8 return fn(n - 1) + fn(n - 2); 9 } 10 11 }
但是考慮不夠全面,1.沒有考慮會不會減到0或者負數 2. 如果n的數值小還行,,n為100的情況,遞歸太深,這樣會極大的消耗你的內存,
然后問度娘:https://baike.baidu.com/item/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97
像高中和大學那會,,一般這種都是有通項公式的,不過推導過程太過燒腦,請參照度娘提供的方法;
然后根據通項公式整理代碼如下:
1 public static double fnn(int n) { 2 double a = Math.sqrt(5); 3 double b = 1 / a; 4 double c = Math.pow((1 + a) / 2, n); 5 double d = Math.pow((1 - a) / 2, n); 6 double e = b * (c - d); 7 return e; 8 } 9 10 public static void main(String[] args) { 11 System.out.println(fnn(10)); 12 }
我想面試如果考這種題目,一般是考察遞歸,內存溢出,算法,,,這個僅代表個人愚見,代碼也有不足支出,僅供大家呵呵,歡迎大家提意見.
割=================================================================================================
最進有了新的想法:尾遞歸
如果一個函數中所有遞歸形式的調用都出現在函數的末尾,我們稱這個遞歸函數是尾遞歸的。當遞歸調用是整個函數體中最后執行的語句且它的返回值不屬於表達式的一部分時,這個遞歸調用就是尾遞歸。尾遞歸函數的特點是在回歸過程中不用做任何操作,這個特性很重要,因為大多數現代的編譯器會利用這種特點自動生成優化的代碼。
百度百科:https://baike.baidu.com/item/%E5%B0%BE%E9%80%92%E5%BD%92/554682
百科解釋的很清楚,,那么這道題就可以這么做了:
1 // 0 2 // 102334155 3 private static Integer fun1(int n, int ret1, int ret2) { 4 if (n == 0) { 5 return ret1; 6 } 7 return fun1(n - 1, ret2, ret1 + ret2); 8 9 } 10 11 // 1361 12 // 102334155 13 private static Integer fun(int n) { 14 if (n == 0) { 15 return 0; 16 } else if (n == 1 || n == 2) { 17 return 1; 18 } else { 19 return fun(n - 1) + fun(n - 2); 20 } 21 } 22 23 public static void main(String[] args) { 24 long t0 = System.currentTimeMillis(); 25 Integer fun = fun1(40, 0, 1); 26 long t1 = System.currentTimeMillis(); 27 System.out.println(t1 - t0); 28 System.out.println(fun); 29 }
里面有兩種我本地的運行時間和結果,,,大大的優化啊,