回溯演算法-深度優先搜尋
阿新 • • 發佈:2021-12-15
來源於leetcode一道中等難度的題,匹配括號。
回溯法-深度優先搜尋
回溯法思路的簡單描述是:把問題的解空間轉化成了圖或者樹的結構表示,然後使用深度優先搜尋策略進行遍歷,遍歷的過程中記錄和尋找所有可行解或者最優解。
回溯法按深度優先策略搜尋問題的解空間樹。首先從根節點出發搜尋解空間樹,當演算法搜尋至解空間樹的某一節點時,先利用剪枝函式判斷該節點是否可行(即能得到問題的解)。如果不可行,則跳過對該節點為根的子樹的搜尋,逐層向其祖先節點回溯;否則,進入該子樹,繼續按深度優先策略搜尋。
回溯法的基本行為是搜尋,搜尋過程使用剪枝函式來為了避免無效的搜尋。
剪枝函式包括兩類:1. 使用約束函式,剪去不滿足約束條件的路徑;
2.使用限界函式,剪去不能得到最優解的路徑。
(在搜尋過程中剪掉已經出現不符合條件的路徑,避免繼續向下展開)
問題的關鍵在於如何定義問題的解空間,轉化成樹(即解空間樹)。解空間樹分為兩種:子集樹和排列樹。兩種在演算法結構和思路上大體相同。
當問題是要求滿足某種性質(約束條件)的所有解或最優解時,往往使用回溯法。
LeetCode題解程式碼
檢視程式碼
public List generateParenthesis(int n) { List list = new ArrayList<>(); if (n == 0){ return list; } dfs("",n,n,list); return list; } public void dfs(String res ,int left,int right,List temp){ //判斷是否已經達到了葉子結點,也就是最終解 if (left == 0 && right == 0){ temp.add(res); return; } //剪枝 //當遍歷過程中發現已經有了不符合條件的情況產生,剪去這條路徑,減少不必要的搜尋過程 if (right < left){ return; } //樹的兩個節點,也就是兩個不同的路徑,向下遍歷 //採用遞迴的形式,將兩種情況分解為樹的兩個節點,向下遍歷 //這裡遞迴進去之後,會在這個結點為根的情況下再次產生兩個結點,直到遍歷到最後的葉子結點 if (left > 0){ dfs(res + "(",left - 1,right,temp); } if (right > 0){ dfs(res + ")",left,right - 1,temp); } }