目录
LeeCode39. Combination Sum
LeeCode39. Combination Sum II
LeeCode131. Palindrome Partitioning
LeeCode39. Combination Sum
题目地址:力扣
题目类型:回溯、组合
class Solution {
private:
vector<vector<int>> ans;
vector<int> path;
void DFS(vector<int>& candidates, int target, int start, int sum) {
if (sum > target) return ;
if (sum == target) {
ans.emplace_back(path);
return ;
}
// 剪枝操作,可以直接去重
for (int i = start; i < candidates.size(); ++i) {
path.emplace_back(candidates[i]);
sum += candidates[i];
DFS(candidates, target, i, sum);
sum -= candidates[i];
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
DFS(candidates, target, 0, 0);
return ans;
}
};
LeeCode39. Combination Sum II
题目地址:力扣
题目类型:回溯、组合
去重思路:
- 这里分为同一树枝使用过&同一树层使用过;同一树枝使用过不会造成什么影响,同一树层使用过会导致重复
- 同一树枝:candidates[i - 1] == candidates[i] && used[i - 1] == true;
- 同一树层:candidates[i - 1] == candidates[i] && used[i - 1] == false;
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool> used(candidates.size(), false);
sort(candidates.begin(), candidates.end());
DFS(candidates, target, 0, 0, used);
return ans;
}
private:
vector<vector<int>> ans;
vector<int> path;
void DFS(vector<int>& candidates, int target, int start, int sum, vector<bool>& used) {
if (target == sum) {
ans.emplace_back(path);
return ;
}
for (int i = start; i < candidates.size() && candidates[i] + sum <= target; ++i) {
// 这里分为同一树枝使用过&同一树层使用过;同一树枝使用过不会造成什么影响,同一树层使用过会导致充分
// 同一树枝:candidates[i - 1] == candidates[i] && used[i - 1] == true;
// 同一树层:candidates[i - 1] == candidates[i] && used[i - 1] == false;
if (i > 0 && candidates[i - 1] == candidates[i] && used[i - 1] == false) continue;
used[i] = true;
sum += candidates[i];
path.emplace_back(candidates[i]);
DFS(candidates, target, i + 1, sum, used);
path.pop_back();
sum -= candidates[i];
used[i] = false;
}
}
};
LeeCode131. Palindrome Partitioning
题目地址:力扣
题目类型:回溯、分割
重点:本题回溯枚举的是分割点的位置
class Solution {
private:
vector<vector<string>> ans;
vector<string> path;
// 区间为:[left, right]
bool isHui(string &s, int left, int right) {
while (left <= right) {
if (s[left] != s[right]) return false;
left++;
right--;
}
return true;
}
// index指向当前应该开始的位置,在切割时,实际是一个闭区间
void DFS(string s, int index) {
if (index == s.size()) {
ans.emplace_back(path);
return ;
}
for (int i = index; i < s.size(); ++i) {
// 判断当前的子串是否是回文,不是的话就跳过
if (!isHui(s, index, i)) continue;
path.emplace_back(s.substr(index, i - index + 1));
DFS(s, i + 1);
path.pop_back();
}
}
public:
vector<vector<string>> partition(string s) {
DFS(s, 0);
return ans;
}
};