1. 程式人生 > 其它 >回溯演算法-深度優先搜尋

回溯演算法-深度優先搜尋

來源於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);
		}
	}