组合总和
1.给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& num,int target,int sum,int startIndex)
{
if(sum==target)
{
result.push_back(path);
return ;
}
for(int i=startIndex;i<num.size()&&sum+num[i]<=target;i++)
{
path.push_back(num[i]);
sum+=num[i];
backtracking(num,target,sum,i);
sum-=num[i];
path.pop_back();
}
}
vector<vector<int>> combine(vector<int>& num,int target)
{
path.clear();
result.clear();
sort(num.begin(),num.end());
backtracking(num,target,0,0);
return result;
}
int main()
{
vector<int> num={2,5,3};
vector<vector<int>> t=combine(num,7);
for(const auto& n:t)
{
for(int m:n)
{
cout<<m<<" ";
}
cout<<endl;
}
return 0;
}
思路:本题搜索的过程抽象成树形结构如下:
注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回!
二维数组result存放结果集,数组path存放符合条件的结果。
sum变量来统计单一结果path里的总和,从叶子节点可以清晰看到,终止只有两种情况,sum大于target和sum等于target。单层for循环依然是从startIndex开始,搜索candidates集合。
剪枝操作:对于sum已经大于target的情况,其实是依然进入了下一层递归,只是下一层递归结束判断的时候,会判断sum > target的话就返回。其实如果已经知道下一层的sum会大于target,就没有必要进入下一层递归了。