回溯算法
回溯
指的是狀態重置
,可以理解爲回到過去
,恢復現場
是在編碼的過程中,是爲了節約空間而使用的一種技巧,而回溯算法其實是深度優先遍歷
特有的一種現象。之所以是深度優先遍歷
,是因爲我們要解決的問題通常是在一顆樹上完成的,在這顆樹上搜索需要的答案,一般使用深度優先遍歷
畫遞歸樹解決
回溯算法基本框架
解決一個回溯問題,實際上就是一個決策 樹的遍歷過程,一般來說我們需要解決三個問題
路徑:也就是已經做出的選擇
選擇列表:也就是你當前可以做的選擇
結束條件:也就是到達決策樹底層,無法再做選擇的條件
List result = new ArrayList<>();
public void dfs(路徑,選擇列表){
if(滿足結束條件){
result.add(結果);
}
for(選擇:選擇列表){
做出選擇:
backtrack(路徑,選擇列表)
撤銷選擇
}
}
其中最關鍵的點就是:
在遞歸之前做選擇,在遞歸之後做出選擇
解題思路如何找
畫圖,畫圖,畫圖
找到其對應的樹的結構
剪枝的問題
什麼是
剪枝
:在遞歸回溯
的時候,可能在目前的情況下接着遞歸得到的結果一定是錯誤的,即不符合題意的
,也就沒有必要接着再這條葉子上進行接下來的查找,可以提前結束這條遞歸鏈
關鍵是如何進行剪枝
問題
適用的場景
組合問題,從一堆數據中查找滿足某種條件的所有數據組合
排列問題:對一堆數據進行排列
查找問題:從數據中查找滿足某種問題的所有可能
題型一:排列
- 對不含重複的元素集合進行排列
- 對含有重複的元素集合進行排列
題型二:組合
集合中的元素是否重複
;