一、组合总和
这题一开始没用startindex做,直接回溯穷举,导致最后类似【3,3,2】和【3,2,3】没有去重,用了startindex以后,就不会出现后面的数小于前面的数,只能是大于等于的情况,而大于这种情况本题允许取,所以可以是大于等于,且要注意,回溯函数的index要传入i,即当前遍历到的点的下标
class Solution {
public:
vector<vector<int>>result;
vector<int>path;
void backtracking(vector<int>nums,int target,int sum,int startindex){
if(sum==target){
result.push_back(path);
return;
}
if(sum>target)return;
for(int i=startindex;i<nums.size();i++){
path.push_back(nums[i]);
sum+=nums[i];
backtracking(nums,target,sum,i);
sum-=nums[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
};
二、组合总和Ⅱ
这里比较难的地方是去重操作,用了一个used数组来记录是否使用过前面的 元素,在判断之前,主函数中应该先把candidates排序,这样才能比较i和i-1的大小,重复了,就砍去宽度部分,用continue来中止for循环
class Solution {
public:
vector<vector<int>>result;
vector<int>path;
void backtracking(vector<int>&candidates,int target,int startindex,int sum,vector<bool>&used){
if(sum==target){
result.push_back(path);
return;
}
for(int i=startindex;i < candidates.size()&& sum +candidates[i]<=target;i++){
if(i>0&&used[i-1]==false&&candidates[i]==candidates[i-1])continue;
path.push_back(candidates[i]);
sum+=candidates[i];
used[i]=true;
backtracking(candidates,target,i+1,sum,used);
used[i]=false;
sum-=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool>used(candidates.size(),0);
sort(candidates.begin(),candidates.end());
backtracking(candidates,target,0,0,used);
return result;
}
};
三、切割回文串
这里要写一个判断是否为回文数的函数,
1.传入的不需要是已经切割好了的字符串,可以是传入待切割的字符串的首尾位置,在判断函数内部切割。
2.需要string 一个str来接收符合回文条件的字符串。这里用到了s.substr()方法(后边的参数分别是开始的下标和要截取的长度)
3.要注意continue的运用,这两天的剪枝操作、排除不符合条件的情况都用到了continue来中止循环,而这个语句是我经常忘记用的。
4.startindex指示字符下标,可以给他想象成给这个所指下标字符前面加了一道隔板/切割线,因此只有在下标索引到s.size()的前面,即最后一个元素的后面时,停止递归开始回溯。
class Solution {
public:
vector<string>path;
vector<vector<string>>result;
bool ispartition(string&s,int start,int end){
int i=start;
int j=end;
while(i<j){
if(s[i]!=s[j])return false;
i++;
j--;
}
return true;
};
void backtracking(string&s,int startindex){
if(startindex==s.size()){
result.push_back(path);
return;
}
for(int i=startindex;i<s.size();i++){
if(ispartition(s,startindex,i)){
string str=s.substr(startindex,i-startindex+1);
path.push_back(str);
}
else continue;
backtracking(s,i+1);
path.pop_back();
}
};
vector<vector<string>> partition(string s) {
backtracking(s,0);
return result;
}
};