39. 组合总和
输入数组和目标数;输出解集二维数组;
终止条件:sum==target,result.push_back(),return;
sum>target,return;
单层循环:sum+=path
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int> &candidates, int target,int sum,int startIndex){
if(sum==target){
result.push_back(path);
return;
}
if (sum > target)
{
return;
}
for(int i=startIndex;i<candidates.size();i++){
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates,target,sum,i);
sum -= candidates[i];
path.pop_back();
}
}
public :
vector<vector<int>> combinationSum(vector<int> &candidates, int target)
{
result.clear();
path.clear();
backtracking(candidates,target,0,0);
return result;
}
};
剪枝优化:
再上一个版本中,即使sum大于target,也要进入下一层递归,这里优化可以在本层拒绝进入下一层;就是在for循环中将:
for(int i=startIndex;i<candidates.size();i++)
换成
for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++)
40.组合总和II
输入数组和目标数;输出解集二维数组;
终止条件:sum==target,result.push_back(),return;
sum>target,return;
单层循环:要考虑同层不能相同
class Solution
{
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int> &candidates, int target, int sum, int startIndex)
{
if (sum == target)
{
result.push_back(path);
return;
}
if (sum > target)
{
return;
}
for (int i = startIndex; i < candidates.size(); i++)
{
if(i>startIndex && candidates[i] == candidates[i-1]){
continue;
}
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, target, sum, i+1);
sum -= candidates[i];
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum2(vector<int> &candidates, int target)
{
result.clear();
path.clear();
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, 0);
return result;
}
};
131.分割回文串
回溯三部曲:输入字符串和起始值;
终止条件:切割线切到了字符串最后面,说明找到了一种切割方法,此时就是本层递归的终止条件。在处理组合问题的时候,递归参数需要传入startIndex,表示下一轮递归遍历的起始位置,这个startIndex就是切割线。
做一个判别回文串的函数
class Solution {
private:
vector<vector<string>> result;
vector<string> path;
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)){
string str = s.substr(startIndex, i - startIndex + 1);
}else{
continue;
}
backtracking(s,i+1);
path.pop_back();
}
}
bool isPalindrome(const string& s,int start,int end){
for (int i = start, j = end; i < j;i++,j--){
if(s[i]!=s[j]){
return false;
}
}
return true;
}
public:
vector<vector<string>> partition(string s) {
result.clear();
path.clear();
backtracking(s,0);
return result;
}
};