1. 程式人生 > >Java實現斐波那契數高效演算法

Java實現斐波那契數高效演算法

前段時間去面試,被問到了斐波那契數演算法,在此回顧總結一下。

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)