LeetCode 39 组合总和 2023.11.20
class Solution {
public:
//创建遍历所用的变量,当前和sum,当前遍历值cur数组,最终答案数组
int sum;
vector<int> cur;
vector<vector<int>> result;
//递归回溯遍历
void backtracking(vector<int>& candidates, int target, int start)
{
//判断条件:当前和与目标值相等时,记入答案后返回
if(sum == target)
{
result.push_back(cur);
return;
}
//这里题目没明确是升序数组,但实际是,所以这个算优化
else if(sum > target)
return;
//递归回溯
for (int i = start; i < candidates.size(); i++)
{
//加入当前节点
cur.push_back(candidates[i]);
//更新和值
sum += candidates[i];
//递归
backtracking(candidates, target, i);
//回溯及更新和值
cur.pop_back();
sum -= candidates[i];
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
//初始化成员变量,实际不更新也可以
sum = 0;
cur.clear();
result.clear();
//判断如果数组为空则不递归回溯
if(candidates.empty())
return result;
//递归回溯
backtracking(candidates, target, 0);
return result;
}
};
LeetCode 40 组合总和-ii 2023.11.20
class Solution {
public:
创建遍历所用的变量,当前和sum,当前遍历值cur数组,最终答案数组可以用vector也可以set
int sum;
vector<int> cur;
vector<vector<int>> result;
// set<vector<int>> result;
//递归回溯遍历
void backtracking(vector<int>& candidates, int target, int start)
{
//判断条件:当前和与目标值相等时,记入答案后返回
if(sum == target)
{
result.push_back(cur);
return;
}
//因为先进行了数组排序,当和值超过目标值后,不必要再往下遍历了
else if(sum > target)
return;
//递归回溯
for (int i = start; i < candidates.size(); i++)
{
//加入当前节点
cur.push_back(candidates[i]);
//更新和值
sum += candidates[i];
//递归
backtracking(candidates, target, i+1);
//回溯及更新和值
cur.pop_back();
sum -= candidates[i];
//避免重复数值导致重复答案的出现,开始遍历下一个不同的值
while ((i+1) < candidates.size() && candidates[i] == candidates[i+1])
i++;
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
//初始化成员变量,实际不更新也可以
sum = 0;
cur.clear();
result.clear();
//判断如果数组为空则不递归回溯
if(candidates.empty())
return result;
// return vector<vector<int>>(result.begin(), result.end());
//先排序后递归回溯
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0);
return result;
//return vector<vector<int>>(result.begin(), result.end());
}
};
LeetCode 131 分割回文串 2023.11.20
class Solution {
public:
//创建遍历所用的变量,当前遍历字符串cur,最终答案数组result
vector<string> cur;
vector<vector<string>> result;
//递归回溯遍历
void backtracking(string s, int start)
{
//递归退出条件,当遍历位置到达字符串尾部时,
//说明前面遍历的子字符串都满足回文串条件,记入答案数组内并返回
if(start >= s.size())
{
result.push_back(cur);
return;
}
//递归回溯
for (int i = start; i < s.size(); i++)
{
//用于判断是否为回文串的标志,初始化标志为是
int sym = 1;
//判断遍历字符串substr[start, i-start+1]是否为回文串,两种方法
// for (int j = start; j <= start + (i-start)/2; j++)
// {
// if(s[j] != s[i-j+start])
// {
// sym = 0;
// break;
// }
// }
for (int j = start, k = i; j < k; j++, k--)
{
if(s[j] != s[k])
{
sym = 0;
break;
}
}
//如果判断子字符是回文串,则记录到当前答案内,再遍历后面字符串
if(sym)
cur.push_back(s.substr(start, i-start+1));
//如果当前子字符串都不是回文串,就不用再切割判断后面字符串了,进行下次循环
else
continue;
//递归判断
backtracking(s, i+1);
//回溯
cur.pop_back();
}
}
vector<vector<string>> partition(string s) {
cur.clear();
result.clear();
if(s.empty())
return result;
backtracking(s, 0);
return result;
}
};