39.组合总和
题目
要求:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的同一个数字可以无限制重复被选取。
因为可以不停的用一个数字,所以在单层递归时不用传入i+1,继续传入i就好。
vector<vector<int>> result;
vector<int> path;
int sum=0;
void backtracking(vector<int>& candidates,int target,int startindex){
if(sum>target)
return;
if(sum==target){
result.push_back(path);
return;
}
for(int i=startindex;i<candidates.size();i++){
path.push_back(candidates[i]);
sum+=candidates[i];
backtracking(candidates,target,i);
//
sum-=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
int startindex=0;
sort(candidates.begin(),candidates.end());
backtracking(candidates,target,startindex);
return result;
}
40.组合总和2
题目
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。
这题难在去重:
void backtracking(vector<int> candidates,int target,int startindex){
if(sum>target)
return;
if(sum==target)
{
result.push_back(path);
return;
}
for(int i=startindex;i<candidates.size();i++){
path.push_back(candidates[i]);
sum+=candidates[i];
backtracking(candidates,target,startindex);
path.pop_back();
sum-=candidates[i];
while(i<candidates.size()-1&&candidates[i]==candidates[i+1])
i++;//当然也可以写在开头
//if(i>startidnex&&candidates[i]==candidates[i-1]);
}
其实本题的去重方法和三数之和是一样的
三数之和
分割回文串
题目
切割问题和组合问题是一样的,如果不考虑回文的问题,但看怎么切割,那其实就是看
在一组数(1,2,3,4,5)中,能有多少种包含末尾数字的组合,12345,2345,245…
而这些数字就代表着子串数字的下标。
void cut(string s, int startindex){
if(startindex==s.size())//到了字符串的最后
{
result.push_back(path);
return;
}
for(int i=startindex;i<s.size();i++){
string temp(s.begin()+startindex,s.begin()+i+1);
//同层从左向右遍历,a->aa->aab;见上图;
path.push(temp);
cut(s,i+1);
path.pop_back();
}
}
但是由于还要判断是不是回文串,所以可以再写个函数来判断:
bool ishuiwen(string s){
string temp=s;
reverse(temp.begin(),temp.end());
return temp==s;//将s翻转看是否相等
}
完整:
void cut(string s, int startindex){
if(startindex==s.size())//到了字符串的最后
{
result.push_back(path);
return;
}
for(int i=startindex;i<s.size();i++){
string temp(s.begin()+startindex,s.begin()+i+1);
//同层从左向右遍历,a->aa->aab;
if(ishuiwen(temp)){
path.push(temp);
cut(s,i+1);
path.pop_back();
}
//如果不是的话就往后切割,就可能会是回文,ab->aba;
}
}