Java實現斐波那契數高效演算法
阿新 • • 發佈:2018-11-15
前段時間去面試,被問到了斐波那契數演算法,在此回顧總結一下。
1、什麼是斐波那契數演算法
斐波那契數,亦稱之為斐波那契數列(義大利語: Successione di Fibonacci),又稱黃金分割數列、費波那西數列、費波拿契數、費氏數列,指的是這樣一個數列:1、1、2、3、5、8、13、21、……在數學上,斐波那契數列以如下被以遞迴的方法定義:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字來說,就是斐波那契數列由 0 和 1 開始,之後的斐波那契數列係數就由之前的兩數相加。
2、遞迴呼叫實現
public class Demo { public static void main(String[] args) { //輸出第n項的值 Scanner scan = new Scanner(System.in); System.out.println("請輸入第n項的值:"); int n = Integer.parseInt(scan.nextLine().trim()); System.out.println("f("+n+")="+f(n)); //輸出前n項所有資料 每10個換一行 for(int i=1;i<=n;i++){ System.out.print(f(i)+"\t"); if(i%10==0){ System.out.println(); } } } /** * 傳入引數n 返回值型別為long,若為int可能出現溢位 */ public static long f(int n){ if(n == 1 || n == 2){//引數1或者2時 return 1; }else{ return f(n - 1) + f(n - 2); } } }
次演算法實現了功能,但是在輸入的n值特別大的時候效能會有影響。時間複雜度為O(2^n)。
3、利用三個引數a b c---輸出第n項的值 以及前n項中每一個數
在遞迴呼叫中算n位的時候,需要計算第n-1和n-2位,計算n-1時需要計算n-2和n-3,發現很多都是重複計算。如果直接計算輸出則可以提高效能,降低時間複雜度。
public class Demo2 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); System.out.println("請輸入:"); int n = Integer.parseInt(scan.nextLine().trim()); //設定a b c 的初始值 在後面的程式碼中使a b c 的值不斷變化 long a =1,b = 1,c = 0; System.out.print("前"+n+"項為:\n"+a+"\t"+b+"\t"); for(int i=3;i<=n;i++){//此處要減去兩項 c = a + b; a = b; b = c; System.out.print(c+"\t"); if(i%10==0){ System.out.println(); } } //輸出請第n項的值: System.out.println("\n"+"f("+n+")="+c); } }
現在時間複雜度為O(n)