以斐波那契數列爲例帶你入門動態規劃

我們先來使用遞歸的方法實現斐波那契數列:

    // 遞歸解決斐波那契問題
	public static int f(int N) {
		if (N < 2)
			return N;
		else
			return f(N - 1) + f(N - 2);
	}

遞歸求值的缺點是什麼呢?就是大量數值會被重複計算。舉個例子,我們在計算f(5)的時候計算了f(4)和f(3),在計算f(4)的時候又計算了f(3)和f(2),這裏的f(4)就被重複計算了。如果數據量夠大的話,被重複計算的數據會耗費大量的時間。

我們可以通過一個數組記錄計算過的數據,來節省時間,這樣一來時間上基本就達到最優了,但空間複雜度爲O(N):

這種是自頂向下,記憶化搜索的方式

    // 加了一個緩存數組,記錄計算過的值
	static int[] memo;
	public static int fib1(int N) {
		if (N < 2)
			return N;
		memo = new int[N+1];
		if (memo[N] != -1) {
			memo[N] = f(N - 1) + f(N - 2);
		}
		return memo[N];

	}

 還可以再對空間進行優化,這樣空間複雜度也是O(1):

這是自底向上,動態規劃

// 動態規劃解決斐波那契問題
    public static int f(int p) {
        int p1 = 0, p2 = 1, cur = 0;
        if (p < 2)
            return p;
        for (int i = 2; i <= p; i++) {
            cur = p1 + p2;
            p1 = p2;
            p2 = cur;
        }
        return cur;
    }

最後,放一張圖,讓你一張圖懂得什麼是動態規劃(圖片來自網絡):

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章