[Algo] 2-4. 回溯法 Backtracking
一、回溯法 回溯法與 dfs 相當類似,本質上都是暴力窮舉的演算法,但細微的差異在於: dfs 在遍歷節點。 backtracking 在遍歷樹枝。 站在回溯樹上的一個節點,需要考慮的只有三件事情: 路徑 選擇 終止條件 以全排列問題([Leetcode] 46. permutation)來舉例 全排列問題即給定一組數組 nums,需返回這些數字的所有排列組合,舉例來說,給定一個數組 nums = [1,2,3],那麼它可能的排列會有: [1,2,3] [1,3,2] [2,1,3] [2,3,1] [3,1,2] [3,2,1] 對應上圖的回溯樹來看,我們在每個樹的節點,都會面臨一次決策,站在樹的根時,相當於我們要選擇排列的第一位,而我們有三個選擇,即 1 或 2 或 3。若我們的第一位選擇了 1,代表我們選擇了 \(\text{x}_1=1\) 的路徑,故接下來我們的選擇只剩下兩個,即 2 或 3。當我們繼續往下做,直到子葉節點時,代表我們已經沒有選擇可選,此時就是我們的終止條件。 回憶我們在二叉樹中練習過前序、中序、後序的思維,前序與後序代表我們在遍歷節點前與後的時間點,而在回溯法,這兩個時間點,各自代表了 將選擇加入路徑 從路徑中撤銷選擇 用二叉樹程式碼來說明即: void traverse(TreeNode* root){ if (!root) return; // preorder: do option traverse(root->left); traverse(root->right); // postorder: retrieve option } N-ary 樹: class Node{ int val; vector<Node*> children; }; void traverse(Node* root){ if (!...