代码随想录刷题随记23-回溯3
39. 组合总和
leetcode链接
注意同一个 数字可以 无限制重复被选取
怎么体现这个可以重复取的思想很重要
解题代码:
class Solution {
public:
void backtrace( vector<vector<int>>& ret,vector<int> &path,vector<int>& candidates,int target,int index,int &sum){
if(sum==target){
ret.push_back(path);
return ;
}
if(sum>target)
return;
for(int i=index;i<candidates.size();i++) {
path.push_back(candidates[i]);
sum+=candidates[i];
//重用
backtrace(ret, path,candidates,target, i, sum);
sum-=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> ret;
vector<int> path;
int sum=0;
backtrace(ret,path, candidates, target, 0, sum);
return ret;
}
};
40.组合总和II
leetcode链接
candidates 中的每个数字在每个组合中只能使用一次
同时因为candidite集合里面的数本来就有一样的,所以有肯能虽然取数顺寻不一致,但是结果集合相同的问题:
需要去重
去重的关键在于同一层不能重复,纵向上可以重复:
可以先对candidates进行排序,这样比较容易跳过
解题代码:
class Solution {
public:
void backtrace( vector<vector<int>>& ret,vector<int>& candidates,int target,int sum,vector<int> & path,int index,vector<bool> &use){
if(target==sum){
ret.push_back(path);
return;
}
if(sum>target)
return;
for(int i=index;i<candidates.size();i++){
if(i>0&&candidates[i]==candidates[i-1]&&(use[i-1]==false))
continue;
path.push_back(candidates[i]);
sum+=candidates[i];
use[i]=true;
backtrace(ret,candidates, target, sum, path, i+1,use);
sum-=candidates[i];
use[i]=false;
path.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<vector<int>> ret;
vector<int> path;
int sum=0;
std::sort(candidates.begin(),candidates.end());
vector<bool> use(candidates.size(),false);
backtrace(ret, candidates, target, sum,path, 0,use);
return ret;
}
};
131.分割回文串
class Solution {
public:
bool isstr(string str){
if(str.size()==1)
return true;
int l=0;
int r=str.size()-1;
while(l<r){
if(str[l]!=str[r])
return false;
l++;
r--;
}
return true;
}
void backtrace( string s,vector<vector<string>>& ret,vector<string> &path,int curind,int lastind){
if(curind==s.size()){
ret.push_back(path);
return;
}
string substring=s.substr(lastind,curind-lastind);
//从当前切
substring+=s[curind];
if(isstr(substring)){
path.push_back(substring);
backtrace(s, ret, path, curind+1, curind+1);
path.pop_back();
}
substring.pop_back();
//当前不切
if(curind+1<s.size())
backtrace(s, ret, path, curind+1, lastind);
}
vector<vector<string>> partition(string s) {
vector<vector<string>> ret;
vector<string> path;
backtrace(s, ret, path, 0, 0);
return ret;
}
};