LintCode 數字組合 題解
阿新 • • 發佈:2019-01-23
數字組合
給出一組候選數字(C)和目標數字(T),找到C中所有的組合,使找出的數字和為T。C中的數字可以無限制重複被選取。
例如,給出候選陣列[2,3,6,7]和目標數字7,所求的解為:
[7],
[2,2,3]
注意事項
- 所有的數字(包括目標數字)均為正整數。
- 元素組合(a1, a2,
… , ak)必須是非降序(ie, a1 ≤ a2 ≤
… ≤ ak)。
- 解集不能包含重複的組合。
給出候選陣列[2,3,6,7]和目標數字7
返回 [[7],[2,2,3]]
解題思路:
主要方法是進行遞迴和回溯。
回溯的觸發條件是當前算出的sum==target或者sum>target
遞迴的時候就是從當前cur位置的數一直新增到tem裡,如果遇到回溯的情況,則彈出之前加入的數,同時更新tsum。
描述的不是很清楚,具體思路可以參考一下博文:
需要注意的一點:在進行遞迴和回溯之前需要對candidates陣列進行排序,並且將其中的重複元素進行刪除。否則的話返回的rt陣列中會出現重複的值。
例如輸入為【1,1,2】 2 不刪除重複的1的情況下會返回{【1,1】【1,1】【1,1】【2】}
class Solution { public: /** * @param candidates: A list of integers * @param target:An integer * @return: A list of lists of integers */ void countall(vector<vector<int> >& rt, vector<int>tem, vector<int> candidates, int tsum, int cur, int target) { if (tsum == target) { rt.push_back(tem); return; } if(tsum>target) return; for(int i=cur;i<candidates.size();i++) { tem.push_back(candidates[i]); tsum+=candidates[i]; countall(rt,tem,candidates,tsum,i,target); tsum-=tem[tem.size()-1]; tem.pop_back(); } } vector<vector<int> > combinationSum(vector<int> &candidates, int target) { // write your code here vector<vector<int> > rt; if(candidates.size()==0) return rt; vector<int> tem; sort(candidates.begin(),candidates.end()); candidates.erase( unique( candidates.begin(), candidates.end() ), candidates.end() ); //刪除掉candidate中的重複元素,因為重複元素會導致rt中有重複的解 countall(rt,tem,candidates,0,0,target); return rt; } };