找出无重复元素的正整数数组candidates中元素和为目标数target的所有不同组合,同一个数字可重复选取
回溯三部曲:
1)参数和返回值
2)终止条件
3)单层搜索逻辑
代码
class Solution {
public:
vector path;
vector> result;
void backtracking(vector& candidates,int targetsum,int sum,int startIndex){
if(sum>targetsum) return;
//终止条件
if(sum==targetsum){
result.push_back(path);
return;
}
//单层递归逻辑
for(int i=startIndex;i> combinationSum(vector& candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
};
给数组递增排序,排序后,如果组合中的一个分支使得和(sum+candidates[i])大于targetsum,那么该分支及其后面的分支没有必要存在了,因为和肯定都大于target了
代码
class Solution {
public:
vector path;
vector> result;
void backtracking(vector& candidates,int targetsum,int sum,int startIndex){
//终止条件
if(sum==targetsum){
result.push_back(path);
return;
}
//单层递归逻辑
//注意限制条件是<= 一定要包含等于,因为还要将candidates[i]放入path数组中
for(int i=startIndex;i> combinationSum(vector& candidates, int target) {
//排序
sort(candidates.begin(),candidates.end());
backtracking(candidates,target,0,0);
return result;
}
};
找出正整数数组candidates中使得元素和为target的组合,组合不能重复,数组中每个元素只能使用1次,但是candidates中可能存在重复的元素 例如 [2,2,2] target=4 只有1个组合满足[2 2]要求
回溯三部曲:
1)参数和返回值
2)终止条件
3)单层递归逻辑
本题主要是包含去重的操作 将数组按照增序排列,将相同的元素放在紧邻的位置
代码
class Solution {
public:
vector path;
vector> result;
void backtracking(vector& candidates,int targetsum,int sum,int startIndex,vector& used){
//终止条件
if(sum>targetsum) return;
if(sum==targetsum){
result.push_back(path);
return;
}
//单层递归逻辑
for(int i=startIndex;i0 && candidates[i]==candidates[i-1] && used[i-1]==0) continue;
sum += candidates[i];
path.push_back(candidates[i]);
used[i] = true;
backtracking(candidates,targetsum,sum,i+1,used);//递归
sum -= candidates[i];//回溯
path.pop_back();//回溯
used[i] = false;//回溯
}
}
vector> combinationSum2(vector& candidates, int target) {
//对数组进行排序,使得数组中数值相等的元素可以相邻在一起,这样方便去重
sort(candidates.begin(),candidates.end());
vector used(candidates.size(),false);
backtracking(candidates,target,0,0,used);
return result;
}
};
class Solution {
public:
vector path;
vector> result;
void backtracking(vector& candidates,int targetsum,int sum,int startIndex,vector& used){
//终止条件
if(sum==targetsum){
result.push_back(path);
return;
}
//单层递归逻辑
for(int i=startIndex;i0 && candidates[i]==candidates[i-1] && used[i-1]==0) continue;
sum += candidates[i];
path.push_back(candidates[i]);
used[i] = true;
backtracking(candidates,targetsum,sum,i+1,used);//递归
sum -= candidates[i];//回溯
path.pop_back();//回溯
used[i] = false;//回溯
}
}
vector> combinationSum2(vector& candidates, int target) {
//对数组进行排序,使得数组中数值相等的元素可以相邻在一起,这样方便去重
sort(candidates.begin(),candidates.end());
vector used(candidates.size(),false);
backtracking(candidates,target,0,0,used);
return result;
}
};
将字符串s(仅由小写字母组成)分割成若干回文子串 回文串是正读和反读相同的子串,返回分割方案
回溯三部曲:
1)参数和返回值
2)终止条件
3)单层搜索逻辑
代码
class Solution {
public:
//判断字符串是否是回文串
bool ispalidrom(const string& s,int start,int end){
for(int i=start,j=end;i path;//存放单个分割结果
vector> result;//存放所有分割方案
void backtracking(const string& s,int startIndex){
//终止条件
if(startIndex==s.size()){
result.push_back(path);//path中只存放是回文串的子串
return;
}
//单层搜索逻辑
for(int i=startIndex;i> partition(string s) {
backtracking(s,0);
return result;
}
};