文章目錄
- 40. 組合總和 II
- 題目描述
- 回溯算法
40. 組合總和 II
題目描述
給定一個候選人編號的集合 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。
candidates 中的每個數字在每個組合中只能使用 一次 。
注意:解集不能包含重復的組合。
示例 1:
輸入: candidates = [10,1,2,7,6,1,5], target = 8,
輸出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
示例 2:
輸入: candidates = [2,5,2,1,2], target = 5,
輸出:
[
[1,2,2],
[5]
]
提示:
- 1 <= candidates.length <= 100
- 1 <= candidates[i] <= 50
- 1 <= target <= 30
回溯算法
// 定義一個Solution類,用于解決組合總和II問題
class Solution {
public:// 定義一個公共方法combinationSum2,它接受一個整數數組candidates和一個整數target,// 返回一個二維整數數組,里面包含了所有可以使數字和為target的組合。vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {// 首先對數組進行排序,這會幫助我們更容易地找到組合,并且能夠跳過重復的組合sort(candidates.begin(),candidates.end());// 輸出排序后的數組元素,這一步通常是為了調試for(int i=0;i<candidates.size();i++)cout<<candidates[i]<<" ";// 定義一個布爾向量used,用于標記candidates中的元素是否被用在當前的組合中vector<bool> used(candidates.size(),false);// 調用backstracking函數,開始回溯算法backstracking(candidates, target, 0, 0, used);// 返回所有找到的組合return result;}private:// 定義一個私有變量result,用于存儲所有找到的組合vector<vector<int>> result;// 定義一個私有變量path,用于存儲當前正在考慮的組合vector<int> path;// 定義一個私有函數backstracking,它實現了回溯算法void backstracking(vector<int>& candidates,int target,int sum,int start,vector<bool>& used){// 如果當前組合的數字和大于目標數target,則當前路徑不可能為解,回溯if(sum>target)return;// 如果當前組合的數字和等于目標數target,則找到了一個解,將它添加到result中if(sum==target){result.push_back(path);return;}// 從start開始遍歷candidates數組,嘗試每個可能的元素for(int i=start;i<candidates.size();i++){// 跳過重復的數字,以避免重復的組合,這是因為數組已經排序if(i>0 && candidates[i]==candidates[i-1] && !used[i-1])continue;// 將candidates[i]添加到當前路徑path.push_back(candidates[i]);// 標記該元素為已使用used[i]=true;// 將candidates[i]的值加到當前和上,并遞歸調用backstracking,注意新的start是i+1,因為每個數字只能使用一次sum+=candidates[i];backstracking(candidates, target, sum, i+1, used);// 回溯,將最后一個元素從路徑中刪除并從當前和中減去,取消標記該元素path.pop_back();used[i]=false;// 從當前和中減去candidates[i]的值,為下一次迭代準備sum-=candidates[i];}}
};
代碼主要由以下幾個部分組成:
- combinationSum2 公共方法:對給定數組排序,初始化用于記錄元素使用情況的布爾向量,開始回溯搜索,最后返回結果。
- backstracking 私有方法:實現了回溯算法的核心邏輯,通過遞歸嘗試每個可能的元素,直到找到所有的組合或者終止搜索。
- result 和 path 私有變量:分別用于存儲找到的所有組合結果和當前遞歸路徑中的組合。
- used 布爾向量:用于標記數組 candidates 中的元素是否已經被使用過,以防止在同一路徑中重復使用。