题目内容
给定一组候选数字(没有重复)和一个目标数字,找出候选数字之和与目标数字相等的所有唯一组合。
同一候选数字可以重复出现多次。
注意:
- 所有数字都是正整数
- 解集不能包含重复组合
分析
应用回溯算法来进行求解
- 先对candidates排序
- 用一个vector代替栈来保存candidates的下标,用sum保存当前栈中的和
- 1)当sum小于target时,将candidates中下标为栈顶元素的值入栈(为了避免重复,入栈不能小于该值);2)当sum等于target时,将结果保存,出栈,然后判断栈顶元素是否已经是candidates最后一个元素了,如果是的话继续出栈,最后将栈顶元素加一(candidates下标后移);当sum大于target时,不保存结果,操作和2)相同。
- 最后返回结果
代码
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<vector<int>> rtn;
if(candidates.size() == 0) return rtn;
vector<int> conbination_stack; //保存下标
conbination_stack.push_back(0);
int sum = candidates[0];
while(conbination_stack.size() != 0) {
if(sum < target) {
conbination_stack.push_back(conbination_stack[conbination_stack.size() - 1]);
sum = sum + candidates[conbination_stack[conbination_stack.size() - 1]];
}
else {
if(sum == target) {
vector<int> temp;
for(int i = 0; i < conbination_stack.size(); i++) {
temp.push_back(candidates[conbination_stack[i]]);
}
rtn.push_back(temp);
}
sum = sum - candidates[conbination_stack[conbination_stack.size() - 1]];
conbination_stack.pop_back();
while(conbination_stack.size() != 0 && conbination_stack[conbination_stack.size() - 1] == candidates.size() - 1) {
sum = sum - candidates[conbination_stack[conbination_stack.size() - 1]];
conbination_stack.pop_back();
}
if(conbination_stack.size() != 0) {
sum = sum - candidates[conbination_stack[conbination_stack.size() - 1]] + candidates[conbination_stack[conbination_stack.size() - 1] + 1];
conbination_stack[conbination_stack.size() - 1]++;
}
}
}
return rtn;
}
};
总结
感觉我的代码还是没有达到最优,在入栈出栈的判断上应该还能改进,代码中间如果有不足的地方还望大佬指正!