貪心,分治,回溯,動態規划 4大核心算法思想


4大經典算法問題

如果我們將這四種算法思想分一下類,那貪心、回溯、動態規划可以歸為一類,而分治單獨可以作為一類,因為它跟其他三個都不大一樣。為什么這么說呢?前三個算法解決問題的模型,都可以抽象成我們今天講的那個多階段決策最優解模型,而分治算法解決的問題盡管大部分也是最優解問題,但是,大部分都不能抽象成多階段決策模型

貪心

就是每次取最優,最大解。局部最優,得出全局最優。它是動態規划的一種特例。

實際上,用貪心算法解決問題的思路,並不總能給出最優解,目前使用的比較少,需要針對非常特殊的數據場景。

分治算法(divide and conquer)

分治算法用四個字概括就是“分而治之”,將原問題划分成 n 個規模較小而結構與原問題相似的子問題,遞歸地解決這些子問題,然后再合並其結果,就得到原問題的解

分治算法是一種處理問題的思想,遞歸是一種編程技巧

要解決這種數據量大到內存裝不下的問題,我們就可以利用分治的思想。我們可以將海量的數據集合根據某種方法,划分為幾個小的數據集合,每個小的數據集合單獨加載到內存來解決,然后再將小數據集合合並成大數據集合。實際上,利用這種分治的處理思路,不僅僅能克服內存的限制,還能利用多線程或者多機處理,加快處理的速度。

for example

在統計方面比較多,比如統計我國人口,要知道我國人口就要先知道每個省人口,要知道省人口就要知道每個市人口,要知道市人口就要知道每個區縣人口,直到村社區,然后匯總求的總人數。

回溯

回溯的處理思想,有點類似枚舉搜索。我們枚舉所有的解,找到滿足期望的解。為了有規律地枚舉所有可能的解,避免遺漏和重復,我們把問題求解的過程分為多個階段。每個階段,我們都會面對一個岔路口,我們先隨意選一條路走,當發現這條路走不通的時候(不符合期望的解),就回退到上一個岔路口,另選一種走法繼續走。

常見問題,八皇后和背包的問題。

回溯的問題就是,時間復雜度為O(n^2), 指數級別,復雜度很高。一般使用遞歸來實現,我們會使用備忘錄去記錄已經計算過的情況,避免重復計算,有時候我們也可以根據實際情況進行剪枝,加快查詢。

動態規划 dynamic programing 又叫 DP

我們把問題分解為多個階段,每個階段對應一個決策。我們記錄每一個階段可達的狀態集合(去掉重復的),然后通過當前階段的狀態集合,來推導下一個階段的狀態集合,動態地往前推進。

大部分動態規划能解決的問題,都可以通過回溯算法來解決,只不過回溯算法解決起來效率比較低,時間復雜度是指數級的。動態規划算法,在執行效率方面,要高很多。盡管執行效率提高了,但是動態規划的空間復雜度也提高了,所以,很多時候,我們會說,動態規划是一種空間換時間的算法思想。

什么樣的問題適合用動態規划來解決呢?換句話說,動態規划能解決的問題有什么規律可循呢?

一般是用動態規划來解決最優問題,而解決問題的過程,需要經歷多個決策階段。每個決策階段都對應着一組狀態。然后我們尋找一組決策序列,經過這組決策序列,能夠產生最終期望求解的最優值。

三個特征

1. 最優子結構

最優子結構指的是,問題的最優解包含子問題的最優解。反過來說就是,我們可以通過子問題的最優解,推導出問題的最優解。

我們也可以理解為,后面階段的狀態可以通過前面階段的狀態推導出來。

2. 無后效性

后效性有兩層含義,含義是,在推導后面階段的狀態的時候,我們只關心前面階段的狀態值,不關心這個狀態是怎么一步一步推導出來的,且當前階段的狀態不受后面階段的狀態影響。

3. 重復子問題

不同的決策序列,到達某個相同的階段時,可能會產生重復的狀態。所以一般可以緩存一起來,避免重復計算。

動態規划DP解法思路

先通過回溯分析出是否存在重復子問題,以及是怎么發生的,然后嘗試在紙上畫一下,遞歸樹,看是否能用回溯+備忘錄的方式解決重復子問題。這樣得到的結果與DP最后得到的結果效率差不多。

1. 狀態轉移表法/ 狀態轉移方程法

我們先畫出一個狀態表。狀態表一般都是二維的(可能是三維/四維復雜場景),所以你可以把它想象成二維數組。其中,每個狀態包含三個變量,行、列、數組值。我們根據決策的先后過程,從前往后,根據遞推關系,分階段填充狀態表中的每個狀態。最后,我們將這個遞推填表的過程,翻譯成代碼,就是動態規划代碼了。

比如:  matrix[i][j] + Math.min(states[i][j-1], states[i-1][j]);

第一個,第二個默認值先找出來。

狀態轉移方程法有點類似遞歸的解題思路。我們需要分析,某個問題如何通過子問題來遞歸求解,也就是所謂的最優子結構。根據最優子結構,寫出遞歸公式,也就是所謂的狀態轉移方程。有了狀態轉移方程,代碼實現就非常簡單了。一般情況下,我們有兩種代碼實現方法,一種是遞歸加“備忘錄”,另一種是迭代遞推。

min_dist(i, j) = w[i][j] + min(min_dist(i, j-1), min_dist(i-1, j))

狀態轉移方程是解決動態規划的關鍵

LeetCode 

1. 最小路徑和

https://leetcode-cn.com/problems/minimum-path-sum/  采用dp方程

class Solution {
    public int minPathSum(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        int rows = grid.length, columns = grid[0].length;
        int[][] dp = new int[rows][columns];
        dp[0][0] = grid[0][0];
        for (int i = 1; i < rows; i++) {
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        }
        for (int j = 1; j < columns; j++) {
            dp[0][j] = dp[0][j - 1] + grid[0][j];
        }
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < columns; j++) {
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }
        return dp[rows - 1][columns - 1];
    }
}

 

 2. 硬幣兌換

https://leetcode-cn.com/problems/coin-change/solution/322-ling-qian-dui-huan-by-leetcode-solution/

coins = [1, 2, 5], amount = 11

F(11)=min(F(111),F(112),F(115))+1

3. 乘積最大子數組

https://leetcode-cn.com/problems/maximum-product-subarray/solution/hua-jie-suan-fa-152-cheng-ji-zui-da-zi-xu-lie-by-g/ 

4. 三角形最小路徑和

https://leetcode-cn.com/problems/triangle/

[ [2], [3,4], [6,5,7], [4,1,8,3] ]

定義二維 dp 數組「自底向上的遞推」。

a. 狀態定義:
dp[i][j]表示從點 (i, j) 到底邊的最小路徑和。

b. 狀態轉移:
dp[i][j] = min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j]dp[i][j]=min(dp[i+1][j],dp[i+1][j+1])+triangle[i][j]

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
        // dp[i][j] 表示從點 (i, j) 到底邊的最小路徑和。
        int[][] dp = new int[n + 1][n + 1];
        // 從三角形的最后一行開始遞推。
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle.get(i).get(j);
            }
        }
        return dp[0][0];
    }
}

作者:sweetiee
鏈接:https://leetcode-cn.com/problems/triangle/solution/di-gui-ji-yi-hua-dp-bi-xu-miao-dong-by-sweetiee/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM