LeetCode39.组合总和
思路:
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void back(vector<int>& candidates,int target,int sum,int startindex) {
if(sum > target) return ;
if(sum == target) {
result.push_back(path);
return ;
}
for(int i = startindex;i < candidates.size() ;i++) {
sum += candidates[i];
path.push_back(candidates[i]);
back(candidates,target,sum,i);//不用i+1表示可以重复读取元素了
sum -= candidates[i];
path.pop_back();
}
return ;
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
back(candidates,target,0,0);
return result;
}
};
LeetCode40.组合总和II
题目链接:
思路:
我们要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重。
树层去重(横向)的话,需要对数组排序!
核心思路是如何在循环中就将组合去重。
如果candidates[i] == candidates[i - 1]
并且 used[i - 1] == false
,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1]。
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void tracking(vector<int>& candidates,int target,int sum,int start,vector<bool>& used) {
if(sum > target) return ;
if(sum == target) {
result.push_back(path);
return ;
}
for(int i = start;i < candidates.size();i++) {
//used[i-1] == true,说明同一树枝candidates[i-1]使用过
//used[i-1] == false,说明同一树层candidates[i-1]使用过
//对同一树层使用过的元素跳过
if(i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) continue;
sum += candidates[i];
path.push_back(candidates[i]);
used[i] = true;
tracking(candidates,target,sum,i + 1,used);
sum -= candidates[i];
path.pop_back();
used[i] = false;
}
return ;
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool> used(candidates.size(),false);
//把所有相同元素排在一起,好去重
sort(candidates.begin(),candidates.end());
tracking(candidates,target,0,0,used);
return result;
}
};
LeetCode131.分割回文串
题目链接:131. 分割回文串 - 力扣(LeetCode)
思路:
class Solution {
public:
vector<vector<string>> result;
vector<string> path;//放已经回文的字串
void backtracking(const string& s,int start) {
//如果起始位置已经大于s的大小,说明已经找到一组分割方案
if(start >= s.size()) {
result.push_back(path);
return ;
}
for(int i = start;i < s.size();i++) {
if(isPalindrome(s,start,i)) {//是回文子串
//获取子串
string str = s.substr(start,i - start + 1);
path.push_back(str);
}
else continue;//不是回文跳过
backtracking(s,i + 1);//寻找i+1为起始位置的子串
path.pop_back();//回溯
}
}
bool isPalindrome(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;
}
vector<vector<string>> partition(string s) {
backtracking(s,0);
return result;
}
};