1.组合总和(39题)
题目描述:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
- 所有数字(包括 target)都是正整数。
- 解集不能包含重复的组合。
示例 1:
- 输入:candidates = [2,3,6,7], target = 7,
- 所求解集为: [ [7], [2,2,3] ]
回溯法: 如果是一个集合来求组合的话,就需要startIndex,如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,只是组合情况,与之前组合问题不一致的是该题可以重复选择,主要在于递归函数的startindex选取,
class Solution {
private:
vector<int>path;//路径
vector<vector<int>>result;//结果集
//回溯函数,需要参数:数组,目标,和,组合问题需要startindex来解决
void backtracking(vector<int>& candidates,int target,int sum,int startindex){
if(sum > target){
return ;//如果和大于目标值直接返回
}
if(sum == target){
result.push_back(path);//和和目标值相等,将路径加入结果集中
return ;
}
//组合数组的遍历,遍历的集合树的宽度
for(int i = startindex;i < candidates.size();i++){
sum += candidates[i];//和求法
path.push_back(candidates[i]);//路径加入
backtracking(candidates,target,sum,i);//递归
path.pop_back();//回溯
sum -= candidates[i];//回溯
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
};
减枝操作:对总集合排序之后,如果下一层的sum(就是本层的 sum + candidates[i])已经大于target,就可以结束本轮for循环的遍历。
class Solution {
private:
vector<int>path;//路径
vector<vector<int>>result;//结果集
//回溯函数,需要参数:数组,目标,和,组合问题需要startindex来解决
void backtracking(vector<int>& candidates,int target,int sum,int startindex){
if(sum > target){
return ;//如果和大于目标值直接返回
}
if(sum == target){
result.push_back(path);//和和目标值相等,将路径加入结果集中
return ;
}
//组合数组的遍历,遍历的集合树的宽度,排序进行,如果sum+该值大于了目标值就不进行操作实现减枝
for(int i = startindex;i < candidates.size() && sum + candidates[i] <= target;i++){
sum += candidates[i];//和求法
path.push_back(candidates[i]);//路径加入
backtracking(candidates,target,sum,i);//递归
path.pop_back();//回溯
sum -= candidates[i];//回溯
}
}
public: