39. 组合总和
1. 思路非常简单,会占用一点内存。
2. 这题有两个关键,一个是剪枝。剪枝要注意细节,在for循环里面continue之前要弹出。 第二个关键是,可以使用相同的元素,第一次选2,3,6,7、对应的2选2,3,6,7、 对应的3选3,6,7。 如果对应的3选2,3,6,7 ,就涉及到复杂的去重问题。
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
int calcSum(vector<int>& a){
int sum=0;
for(int i=0;i<a.size();i++)
{
sum+=a[i];
}
return sum;
}
void backtracking(vector<int>& candidates,int target,int startindex){
if(calcSum(path)==target)
{
result.push_back(path);
return;
}
for(int i=startindex;i<candidates.size();i++)
{
path.push_back(candidates[i]);
//剪枝操作,这里一开始忘记 弹出 了,所以报错了
if(calcSum(path)>target)
{
path.pop_back();
continue;
}
backtracking(candidates,target,i);//这里如果是(candidates,target,startindex)就要进行复杂的去重操作
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
path.clear();
result.clear();
backtracking(candidates,target,0);
return result;
}
};
40.组合总和II
自己的版本,跑不出来,有缘再写吧。
//我自己的版本,不能跑,不知道哪里有错
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
int calcSum(vector<int>& a){
int sum=0;
for(int i=0;i<a.size();i++)
{
sum+=a[i];
}
return sum;
}
void backtracking(vector<int>& candidates,int target,int startindex,vector<bool>& used){
if(calcSum(path)==target)
{
result.push_back(path);
return;
}
for(int i=startindex;i<candidates.size();i++)
{
if(i>0 && candidates[i]==candidates[i-1] && used[i-1]==false)
{
//path.pop_back();
continue;
}
//剪枝操作,这里一开始忘记 弹出 了,所以报错了
if(calcSum(path)>target)
{
path.pop_back();
continue;
}
path.push_back(candidates[i]);
used[i]=true;
backtracking(candidates,target,i+1,used);//这里如果是(candidates,target,startindex)就要进行复杂的去重操作
used[i]=false;
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool> used(candidates.size(), false);
path.clear();
result.clear();
// 首先把给candidates排序,让其相同的元素都挨在一起。
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, used);
return result;
}
};
131.分割回文串
1. 要学习思路,怎么用回溯来做分割
2. 三个边界值要想半天,好好捋捋
class Solution {
private:
vector<string> path;
vector<vector<string>> result;
bool isPalindrome(const string& s,int a,int b)
{
for(int i=a,j=b;i<=j;i++,j--)
{
if(s[i]!=s[j])
{
return false;
}
}
return true;
}
void backtracking(const string& s,int startindex)
{
if(startindex>=s.size())
{
result.push_back(path);
return;
}
for(int i=startindex;i<s.size();i++)
{
if(isPalindrome(s,startindex,i))//后面的位置是i
{
string temp=s.substr(startindex,i-startindex+1);//边界值总是捋不清除,讨厌
path.push_back(temp);
}else{
continue;
}
backtracking(s,i+1);//后面那个参数究竟是什么?
path.pop_back();
}
}
public:
vector<vector<string>> partition(string s) {
path.clear();
result.clear();
backtracking(s,0);
return result;
}
};