117、【回溯算法】leetcode ——39. 组合总和:回溯法+剪枝优化(C++版本)
2023-09-11 14:20:01 时间
题目描述
原题链接:39. 组合总和
解题思路
本题的重点是要保证结果与结果之间去重,且一个结果内可含重复数字。去重的方式便是设置下一回遍历的起始位置startIndex
,可保证后续再次遍历的结果不会出现之前遍历过的结果,而与 77. 组合(回溯法+剪枝优化)的区别在于77的startIndex
起始为i + 1可保证不出现重复的数字,而本题起始位i可允许出现重复的数字。
剪枝优化: 让数组从小到大排列,当遍历到当前的数相加后,超过目标值,则可认为后序的数与之相加一定会不满足条件,直接退出。
class Solution {
public:
vector<vector<int>> res;
unordered_map<int, int> record;
void backtracking(vector<int> candidates, int target, int startIndex, vector<int> path) {
if(target == 0) {
res.push_back(path);
return ;
}
for(int i = statIndex; i < candidates.size(); i++) {
// 剪枝优化:之后相加的数会超过target,则直接返回
if(target - candidates[i] < 0) return ;
path.push_back(candidates[i]);
// 因为一个结果内可以包含相同的数字,但结果与结果之间不能为相同集合,所以用下次起始位置为i,保证可含相同数字,但不会用相同结果集合,完成去重
backtracking(candidates, target - candidates[i], i, path);
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> path;
// 先按从小到大排序,保证后续回溯时,按照从小大大增序遍历,可进行提前剪枝
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, path);
return res;
}
};
参考文章:39. 组合总和
相关文章
- [c++菜鸟]《Accelerate C++》读书笔记
- C/C++和Python编程时NULL和None傻傻分不清楚
- C++程序设计教学材料-2011级
- 【C++入门第一期】命名空间 缺省参数 函数重载 的使用方法及注意事项
- 第十二届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组(第一场真题 + 部分题解)
- C++之内部类(嵌套类)与外部类及友元
- 199、【哈希表】leetcode ——6315. 统计范围内的元音字符串数(C++版本)
- 192、【动态规划】leetcode ——64. 最小路径和:回溯法+动态规划(C++版本)
- 159、【动态规划】leetcode ——322. 零钱兑换:二维数组+一维滚动数组(C++版本)
- 142、【回溯算法】leetcode ——37. 解数独:三维信息判定(C++版本)
- 141、【贪心算法】leetcode ——56. 合并区间(区间重叠解法+双指针解法)(C++版本)
- 140、【贪心算法】leetcode ——763. 划分字母区间(区间边界更新)(C++版本)
- 138、【贪心算法】leetcode ——452. 用最少数量的箭引爆气球(贪心区间重叠问题)(C++版本)
- 134、【贪心算法】leetcode ——134. 加油站(贪心策略)(C++版本)
- 131、【贪心算法】leetcode ——55. 跳跃游戏(贪心策略)(C++版本)
- 116、【回溯算法】leetcode ——17. 电话号码的字母组合:回溯法:哈希映射+字符串数组映射(C++版本)
- 106、【树与二叉树】leetcode ——501. 二叉搜索树中的众数:双指针法+哈希表法(C++版本)
- 81、【栈与队列】leetcode ——232. 用栈实现队列(C++版本)
- 73、【数组】leetcode——15. 三数之和(C++/Python版本)
- 64、【链表】leetcode——203. 移除链表元素(C++版本)