题目:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
class Solution {
private:
int sum;
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& candidates, int target, int start)
{
if(sum == target)
{
result.push_back(path);
return;
}
// 这个判断条件写错啦~~~~~~~~~~~~~
// if(path.size() == candidates.size())
// 这里的if 如果加上剪枝的操作,就没必要重复写了
// if(sum > target)
// {
// return;
// }
// 所谓的剪枝操作,就是在for循环中做文章
// 也就是第第二个终止条件做提前的预判,便可以少一层的递归
// 也就是如果已经知道下一层的 sum 会大于 target ,那么就没有必要进入下一层的递归了
// 这里需要先对 candidates 进行排序,排序后结果做加法的话,这样便于划分范围嘛
// 如果出现本层的 sum + candidates[i](也就是下一层的sum) 已经大于 target,就可以结束本轮的for循环
for(int i = start; i < candidates.size() && sum + candidates[i] <= target; i++)
{
path.push_back(candidates[i]);
sum += candidates[i];
// 注意递归的第三个参数
backtracking(candidates, target, i);
path.pop_back();
sum -= candidates[i];
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{
sum = 0;
path.clear();
result.clear();
// 为了可以实现剪枝操作,所以对candidates 进行排序的先
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0);
return result;
}
};