1. 程式人生 > >leetcode回溯法總結

leetcode回溯法總結

2018.7.30

前文:回溯法和dfs是不一樣的,回溯法有自己很獨特的模板,dfs是一種思想,回溯法是dfs的一種實現。
先來看回溯法的典型題型:

Find a path to success 有沒有解
Find all paths to success 求所有解
1.求所有解的個數 2. 求所有解的具體資訊
Find the best path to success 求最優解

對應的三種模板:

第一種,返回值是true/false。
第二種,求個數,設全域性counter,返回值是void;求所有解資訊,設result,返回值void。
第三種,設個全域性變數best,返回值是void。

一般情況下,第二種居多,第二種也是最難理解了,得到了所有可行的解,自然可以得出這些解中的最優解。

下面給出第二種的常見題型和解答:
77. Combinations https://leetcode.com/problems/combinations/description/
在這裡插入圖片描述
在這裡插入圖片描述
Combination Sum https://leetcode.com/problems/combination-sum/description/
在這裡插入圖片描述
在這裡插入圖片描述

Subsets : https://leetcode.com/problems/subsets/
在這裡插入圖片描述
在這裡插入圖片描述

Subsets II (contains duplicates) : https://leetcode.com/problems/subsets-ii/


在這裡插入圖片描述
在這裡插入圖片描述

Permutations : https://leetcode.com/problems/permutations/
在這裡插入圖片描述
在這裡插入圖片描述

總結上述的這些題型就有一個特點,找出滿足給定條件的集合,實際就是滿足條件的結果樹,進行回溯法遍歷即可。
如果題目說,給定一個集合,然後給某種條件,去找到滿足條件的所有結果,這一類都可以用回溯法來完成。
這一類的經典模板如下:
在這裡插入圖片描述

ans用來儲存中間結果,這裡需要說明的是ans是拷貝賦值,也就是說葉子節點的深搜不影響到父節點,所以父節點只需要將當前節點插入的資料彈出即可,那麼遍歷下一個情況的時候,ans就是空的了,相當於當前節點彈出,進行到下一個節點了。
注意點:
start,遍歷的起始位置
ans,中間結果的儲存
pop_back,回溯到上一層

那麼這種回溯的模板和dfs有什麼區別呢?

dfs可以簡單理解為中序遍歷,其實是一種遍歷的方法,它保留了所有的節點資訊,例如遍歷到葉子節點,然後遞歸回來,繼續遍歷右子數,再去遞迴到葉子節點,每個節點的資料都儲存了一遍。

而對於回溯,和dfs不同的是,它往往使用的是迴圈,迴圈遍歷結果的初始可能性。
兩者區別也不是那麼大,只是某一類情況,用回溯更加清楚直接。