Leetcode 39. 组合总和
链接:39. 组合总和
class Solution {
private:
vector<vector<int>> result; // 用于存放符合条件的结果集合
vector<int> path; // 用于存放当前的路径
// 回溯函数,用于搜索符合条件的组合
// candidates: 候选数组
// target: 目标和
// sum: 当前路径上元素的和
// startIndex: 当前搜索的起始位置
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
// 如果当前路径和大于目标和,直接返回,因为已经不可能找到符合条件的组合
if (sum > target) {
return;
}
// 如果当前路径和等于目标和,说明找到了符合条件的组合,将其加入结果集
if (sum == target) {
result.push_back(path);
return;
}
// 从 startIndex 开始搜索可能的组合
for (int i = startIndex; i < candidates.size(); i++) {
// 将当前候选元素加入路径中
sum += candidates[i];
path.push_back(candidates[i]);
// 递归搜索下一个候选元素,startIndex 保持不变,因为一个元素可以被多次选取
backtracking(candidates, target, sum, i);
// 回溯,撤销处理的候选元素,继续尝试其他组合
sum -= candidates[i];
path.pop_back();
}
}
public:
// 主函数,用于找到所有组合的总和等于目标值的情况
// candidates: 候选数组
// target: 目标和
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
// 调用回溯函数开始搜索符合条件的组合
backtracking(candidates, target, 0, 0);
// 返回结果集
return result;
}
};
Leetcode 40. 组合总和 II
链接:40. 组合总和 II
class Solution {
private:
vector<vector<string>> result; // 存放符合条件的结果集合
vector<string> path; // 存放已经回文的子串
// 回溯函数,用于搜索符合条件的分割方案
// s: 待分割的字符串
// startIndex: 当前搜索的起始位置
void backtracking(const string& s, int startIndex) {
// 如果起始位置已经大于等于s的大小,说明已经找到了一组分割方案
if (startIndex >= s.size()) {
result.push_back(path);
return;
}
// 从startIndex开始,尝试分割出回文子串
for (int i = startIndex; i < s.size(); i++) {
// 如果[startIndex, i]区间的子串是回文串
if (isPalindrome(s, startIndex, i)) {
// 获取[startIndex, i]在s中的子串
string str = s.substr(startIndex, i - startIndex + 1);
path.push_back(str); // 将回文子串加入path中
// 递归搜索以i+1为起始位置的子串
backtracking(s, i + 1);
path.pop_back(); // 回溯,撤销本次添加的子串,尝试其他分割方案
}
}
}
// 判断字符串s中从start到end位置的子串是否为回文串
bool isPalindrome(const string& s, int start, int end) {
while (start < end) {
if (s[start] != s[end]) {
return false;
}
start++;
end--;
}
return true;
}
public:
// 主函数,用于生成符合条件的分割方案
// s: 待分割的字符串
vector<vector<string>> partition(string s) {
// 清空结果集
result.clear();
// 调用回溯函数开始搜索符合条件的分割方案
backtracking(s, 0);
// 返回结果集
return result;
}
};
Leetcode 131. 分割回文串
链接:131. 分割回文串
class Solution {
private:
vector<vector<string>> result; // 存放符合条件的结果集合
vector<string> path; // 存放已经回文的子串
// 回溯函数,用于搜索符合条件的分割方案
// s: 待分割的字符串
// startIndex: 当前搜索的起始位置
void backtracking(const string& s, int startIndex) {
// 如果起始位置已经大于等于s的大小,说明已经找到了一组分割方案
if (startIndex >= s.size()) {
result.push_back(path);
return;
}
// 从startIndex开始,尝试分割出回文子串
for (int i = startIndex; i < s.size(); i++) {
if (isPalindrome(s, startIndex, i)) { // 如果是回文子串
// 获取[startIndex,i]在s中的子串
string str = s.substr(startIndex, i - startIndex + 1);
path.push_back(str); // 将回文子串加入path中
} else { // 如果不是回文子串,跳过
continue;
}
backtracking(s, i + 1); // 递归,寻找i+1为起始位置的子串
path.pop_back(); // 回溯过程,弹出本次已经添加的子串,以便尝试其他分割方案
}
}
// 判断字符串s中从start到end位置的子串是否为回文串
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:
// 主函数,用于生成符合条件的分割方案
// s: 待分割的字符串
vector<vector<string>> partition(string s) {
// 清空结果集
result.clear();
// 调用回溯函数开始搜索符合条件的分割方案
backtracking(s, 0);
// 返回结果集
return result;
}
};