组合总和
参见力扣第39-40题
题目如下:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
来源:力扣(LeetCode)
链接
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我不是很会处理这种回溯,动态规划类的问题,在参考了他人的求解之后,使用一下代码求解:
class Solution {
public:
vector<vector<int>> result;
vector<int> temp;
void getRusult(vector<int>& candidates,int pos, int target){
if(target==0){
result.push_back(temp);
return;
}
if(target<0)return;
for(int i=pos;i!=candidates.size();i++){
temp.push_back(candidates[i]);//处理第i个元素
getRusult(candidates,i,target-candidates[i]);
temp.pop_back();//处理完回退到上一状态
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
getRusult(candidates,0,target);
return result;
}
};
在回溯的过程中,我认为最重要的就是处理完当前元素后得回退到前一步。其中包含了递归。以上代码还可以优化,在for中判断处理当前元素中,是否还有下一个元素。如:
class Solution {
public:
vector<vector<int>> result;
vector<int> temp;
void getRusult(vector<int>& candidates,int pos, int target){
if(target==0){
result.push_back(temp);
return;
}
for(int i=pos;i!=candidates.size()&&(target-candidates[i]>=0);i++){
temp.push_back(candidates[i]);//处理第i个元素
getRusult(candidates,i,target-candidates[i]);
temp.pop_back();//处理完回退到上一状态
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
getRusult(candidates,0,target);
return result;
}
};
如此可以使得后面的一些元素可以直接跳过,少处理一些元素。