1. 程式人生 > 其它 >道長的演算法筆記:通過回溯暴力列舉

道長的演算法筆記:通過回溯暴力列舉

(一) 排列與組合

 通常通常迴圈來做暴力列舉是有侷限性,通過回溯演算法來做列舉往往會更加優雅,回溯演算法中兩個重要的模型便是組合模型與排列模型。

題目 思路描述
LC0077. 組合
LC0078. 子集
組合和子集要求的答案都是順序無關的,因而與排列不同的地方在於,列舉組合的時候,for 迴圈的起始下標是遞增的
LC0040. 組合總和 II
LC0090. 子集 II
對給定的陣列排序,然後回溯的時候如果當前元素與上一個元素相等則跳過當前元素,以此實現去重的效果,兩道題的去重套路都是一模一樣的
LC0216. 組合總和 III 列舉固定長度的組合數,通過排序給定陣列去重,通過資料範圍均為正數故相加不允許超過指定數值 n 來做剪枝
LC0046. 全排列
LC0047. 全排列 II
由於不像組合問題那樣「每次遞迴進入更深層之後列舉的起始下標會遞增」,在求排列問題的時候需要額外的開闢 vist 陣列維護已經訪問的元素,去重思路與上面大同小異。
LC0491. 遞增子序列 本題的去重非常有技巧性,因為這個遞增子序列是要保序的,因而不可以通過排序去重,那麼需要分類討論:(1)前選後選,(2)前不選後選,(3)前選後不選,(4)前不選後不選,(2)與(3)其實能合併歸為一種的,因而維護上一個選擇的元素,遞迴時分為選擇當前元素與不選當前元素兩種情況討論即可。

(二) 去重與剪枝

 當有重複元素的時候,去重往往是通過排序來實現的,但當需要列舉子序列等需要保序的答案時,基於排序的去重思路便不好使了。如果給定了約束條件,一般可以通過約束條件來做剪枝思路。

支援作者