直接用target当做求和,每加入一个数candidates[i]后,就减小
每次循环以index开始,递归时传入i,这样可以重复选择
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void dfs(vector<int>& candidates, int target, int index) {
if (target < 0) return;
if (target == 0) {
res.emplace_back(path);
return;
}
for (int i = index; i < candidates.size(); i++) {
path.emplace_back(candidates[i]);
dfs(candidates, target - candidates[i], i);
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
dfs(candidates, target, 0);
return res;
}
};
不用循环,另外一种思路
class Solution:
def combinationSum(self, candidates: List[int], target: int):
res = []
path = []
n = len(candidates)
def dfs(index, target, path_sum):
if path_sum > target or index == n:
return
if path_sum == target:
res.append(path[:])
return
# 选当前元素
path.append(candidates[index])
dfs(index, target, path_sum + candidates[index])
path.pop()
# 不选当前元素
dfs(index + 1, target, path_sum)
return
dfs(0, target, 0)
return res
直接用candidates[i] == candidates[i-1]去重
注意 i > startIndex,不然会跳过元素重复的组合[1,1,6],若使用candidates[i]==candidates[i + 1]也是同理
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
if (sum == target) {
result.push_back(path);
return;
}
for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
// 要对同一树层使用过的元素进行跳过
if (i > startIndex && candidates[i] == candidates[i - 1]) {
continue;
}
path.push_back(candidates[i]);
backtracking(candidates, target, sum + candidates[i], i + 1);
path.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, 0);
return result;
}
};
双指针法判断是否为回文子串
若分割的子串构成回文串,则可以把答案加入到路径中,若不是则直接i+1
若分割到最后位置,则可以将path加入答案
class Solution {
public:
bool is_palindrome(const string &s, int left, int right) {
for (; left < right; left++, right--) {
if(s[left] != s[right]) return false;
}
return true;
}
vector<string> path;
vector<vector<string>> res;
void dfs(string &s, int index) {
if (index >= s.size()) {
res.emplace_back(path);
return;
}
for (int i = index; i < s.size(); i++) {
if (is_palindrome(s, index, i)) {
path.emplace_back(s.substr(index, i - index + 1));
dfs(s, i + 1); // 寻找i+1为起始位置的子串
path.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
dfs(s, 0);
return res;
}
};