# 【LeetCode】 39. Combination Sum ## Description > Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. > The same repeated number may be chosen from candidates unlimited number of times. > Note: > * All numbers (including target) will be positive integers. > * The solution set must not contain duplicate combinations. > 給一個數字集合(不重複)和一個目標數字target,找到所有集合中的組合,裡面的總合等於target。 > 在集合中的數字可以被重複選取好幾次。 > 注意: > * 所有數字(包含target)都是正整數。 > * 答案集合不應該包含重複的組合。 ## Example: ``` Example 1: Input: candidates = [2,3,6,7], target = 7, A solution set is: [ [7], [2,2,3] ] Example 2: Input: candidates = [2,3,5], target = 8, A solution set is: [ [2,2,2,2], [2,3,3], [3,5] ] ``` ## Solution * 用遞迴求所有組合可能,對於特定狀況進行剪枝加速。 * 情況分為三種: * 拿現在的數字,下一次再拿現在的數字。 * 拿現在的數字,下一次拿下一個數字。 * 不拿現在的數字,下一次拿下一個數字。 * 狀況三和狀況一可能導致取到重複的數字,因此我使用一個`boolean`來判斷是否為重複選取的情況。 * 如果總合已經超過目標值,就直接剪枝,因為數字都是正整數。 * 也因為這點,在遞迴之前得先排列,不然可能錯誤剪枝。 * 可以將一些重複的東西用指標或參考傳遞參數,否則速度會很慢(`call by value`須花費較多時間)。 ### Code ```C++=1 class Solution { public: void FindCombination(vector<vector<int>> &ans,vector<int> &candidates, vector<int> combination,int index,int &target,int sum,bool isDuplicates) { if(index == candidates.size()) return; combination.push_back(candidates[index]); sum+=candidates[index]; if(sum==target) ans.push_back(combination); else if(sum>target) return; else { FindCombination(ans,candidates,combination,index,target,sum,true); FindCombination(ans,candidates,combination,index + 1,target,sum,false); if(!isDuplicates) { sum-=candidates[index]; combination.pop_back(); FindCombination(ans,candidates,combination,index + 1,target,sum,false); } } } vector<vector<int>> combinationSum(vector<int>& candidates, int target) { vector<vector<int>> ans; sort( candidates.begin(), candidates.end() ); FindCombination(ans,candidates,vector<int>(0,0),0,target,0,false); return ans; } }; ``` ###### tags: `LeetCode` `C++`