39. 组合总和
题目链接:39. 组合总和
文档讲解:代码随想录
思路
与77.组合问题类似,只需定义一个全局变量sum
记录当前路径的和,sum
等于target
时,将该路径添加至结果数组。
剪枝:对数组进行排序,然后使用回溯算法,当sum
大于target
时,结束当次循环。
代码
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
result.clear();
path.clear();
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0);
return result;
}
private:
int sum = 0;
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target, int startIndex) {
if (sum == target) {
result.push_back(path);
return;
}
if (sum > target)
return;
for (int i = startIndex; i < candidates.size(); i++) {
sum += candidates[i];
if (sum > target) {
sum -= candidates[i];
continue;
}
path.push_back(candidates[i]);
backtracking(candidates, target, i);
sum -= candidates[i];
path.pop_back();
}
}
};
40.组合总和II
题目链接:40.组合总和II
文档讲解:代码随想录
思路
首先排序数组,然后进行回溯,回溯时需要在横向方向上进行去重,纵向方向不去重。
定义一个used
变量,其中每一位代表数组中对应下标位置的数是否用过,当candidates[i] == candidates[i-1]
时,判断used[i-1]
是否为0,若为0,表示当前数的前一个数没用过,即横向方向上,跳过此次循环;若为1,表示当前数的前一个数用过,即纵向方向上,不进行去重操作。
代码
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int> &candidates, int target) {
used.resize(candidates.size());
sort(candidates.begin(), candidates.end());
backtracking(candidates, 0, target);
return result;
}
private:
vector<vector<int>> result;
vector<int> path;
vector<bool> used;
int sum;
void backtracking(vector<int> &candidates, int startIndex, int target) {
if (sum == target) {
result.push_back(path);
return;
}
if (sum > target)
return;
for (int i = startIndex; i < candidates.size(); i++) {
if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == 0)
continue;
used[i] = 1;
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, i + 1, target);
used[i] = 0;
sum -= candidates[i];
path.pop_back();
}
}
};
131.分割回文串
题目链接:131.分割回文串
文档讲解:代码随想录
思路
该题为分割题型,但与组合题型类似,组合题是选择某个下标的元素,而分割题是选择某个下标之前的元素。
横向方向上,选择不同切割位置;纵向方向上,进行下一次切割。
代码
class Solution {
public:
vector<vector<string>> partition(string s) {
backtracking(s, 0);
return result;
}
private:
bool judge(string s) {
if (s == "")
return false;
for (int i = 0, j = s.size() - 1; i <= j; i++, j--) {
if (s[i] != s[j])
return false;
}
return true;
}
vector<vector<string>> result;
vector<string> path;
int len;
int sub_len;
void backtracking(string s, int startIndex) {
if (sub_len == s.size()) {
result.push_back(path);
return;
}
if (len == s.size())
return;
for (int i = startIndex; i < s.size(); i++) {
string sub_s = s.substr(startIndex, i - startIndex + 1);
len += sub_s.size();
if (judge(sub_s)) {
path.push_back(sub_s);
sub_len += sub_s.size();
}
backtracking(s, i + 1);
len -= sub_s.size();
if (judge(sub_s)) {
path.pop_back();
sub_len -= sub_s.size();
}
}
}
};