LC 39. 组合总和
题目链接: LC 39. 组合总和
思路:每个数字可以被无限选取,但是不能有重复的组合,那么递归的时候每次从包括目前正在递归的值开始遍历,也没有深度要求,那么当sum大于taget时就return,当sum==target就保存,当sum<target时就继续递归。
代码:
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(int sum, int target, int begin, vector<int>& candidates){
if(sum==target){//当总和等于目标值,就保存结果,并且返回
result.push_back(path);
return;
}
if(sum>target){//当总和大于目标值,就直接返回
return;
}
//当目标值小于总和,就进行递归
for(int i=begin; i<candidates.size(); i++){
path.push_back(candidates[i]);
sum = sum+candidates[i];
backtracking(sum, target, i, candidates);//注意也是从第i个开始,因为同一个数可以去无数次
sum = sum-candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(0, target, 0, candidates);
return result;
}
};
LC 40.组合总和II
题目链接:LC 40.组合总和II
思路:递归法,每次将集合中的一个元素放到临时vector中,判断vector中的值是否满足要求,若满足要求就保存vector,并且返回;若不满足要求就继续递归,但递归的集合中没有刚进入vector的元素。注意,题干要求不能有重复解;当一个元素在集合中多次出现时,可以同时使用相同的元素进行组合,但是不能有重复的。去重的思路为:对其进行排序,当一个元素递归完后,若后面一个元素与其相同,那么后面的元素就不用递归了,在二叉树中显示的就是同一层中不能有相同的元素。
代码:
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(int sum, int target, int begin, vector<int>& candidates){
if(sum==target){
result.push_back(path);
return;
}
if(sum>target){
return;
}
for(int i=begin; i<candidates.size(); i++){
sum = sum + candidates[i];
path.push_back(candidates[i]);
backtracking(sum, target, i+1, candidates);
sum = sum - candidates[i];
path.pop_back();
//去重
while(i+1<candidates.size() && candidates[i+1]==candidates[i]){
i++;
}
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
//对candidates进行排序
sort(candidates.begin(), candidates.end());
backtracking(0, target, 0, candidates);
return result;
}
};
LC 131.分割回文串
题目链接:LC 131.分割回文串
思路:将字符串分割成子串,每个子串满足回文子串的要求。先取第一个字符判断是不是回文子串,若是就取后面的一个字符,一直往后;若该字串不为回文字串就将其后面一个字符加入字串中,直到字符串末尾。
代码:
class Solution {
public:
vector<vector<string>> result;
vector<string> path;
//判断s是否是回文子串
bool isPalindrome(string s){
for(int i=0, j=s.size()-1; i<s.size(), j>=0;i++, j--){
if(s[i]!=s[j]){
return false;
}
}
return true;
}
void backtracking(int begin, string s){
if(begin==s.size()){//当遍历到s末尾就结束
result.push_back(path);
return;
}
for(int i=begin; i<s.size(); i++){
//取从开始到i的字串
string tmp = s.substr(begin, i-begin+1);
//若字串为回文字串就将字串放入result中,并递归
if(isPalindrome(tmp)){
path.push_back(tmp);
backtracking(i+1, s);
path.pop_back();
}
//若不是回文字串就进行下次循环
}
}
vector<vector<string>> partition(string s) {
result.clear();
path.clear();
backtracking(0, s);
return result;
}
};