组合总和
问题形貌:给一个组合元素聚集【2 5 3】,都是正整数且没有重复,有一个targer数8, 聚集内里的元素可以重复选,让我们从组合里挑数,使得求和后等于8,返回能求和的组合 , 答案应该是:【 【2,2,2,2】, 【2,3,3】 , 【3,5】 】
画树形布局的注意点:
1、路径取了2后,剩余元素仍旧是2 3 5,因为元素可以重复取。
2、第2条分支,取5,剩余元素要从5后开始算,即5 3, 不能有2,因为如果5 2 那么就和前面的2 5重复了。
3、叶子结点判定是否等于target,如果等于,记录这个答案,返回。如果大于target,已经超了,直接返回。如果小于,继承树深查找。
用代码 实现
和组合问题比较大的差别是:选了一个元素后,剩余元素里,要把已经选过的元素带上,这样才能达到重复选取目地。
其他方面和组合问题差不多,只不过是用一个组合的和target,限定树的高度。
回溯三部曲实现:
1、函数返回值 一样平常是void
2、确定停止条件
3、单层搜索逻辑
- vector<vector<int>> result;
- vector<int> path;
- sum判断path路上的和是否等于target。
- int sum;
- startIndex 作用:在第2个分支如何知道从下一个位置开始找,是for循环变量的开始位置。
- void backtracking(candidate, target, sum, startIndex){
- if(sum > taeget) return;
- if(sum == target){
- result.push_back(path);
- return;
- }
- //单层搜索逻辑,for循环里面的i控制左右,即for的i控制分支, 里面的递归控制高度
- for(int i = startIndex; i<candidate.size();i++){
- path.push_back(candidate[i]);
- sum += candidate[i];
- backtracing(candidate, target, sum, i);
- //回溯不能掉,如何收集信息,就如何吐出去。
- sum -= candidate[i];
- path.pop_back();
- }
- return;
- }
复制代码 这里附上我的完整的解题代码
- class Solution {
- public:
- vector<vector<int>> result;
- vector<int> path;
- int sum=0;
- int startIndex=0;
- void backtracking(vector<int>& candidates, int target, int sum, int startIndex){
- if(sum > target) return;
- if(sum == target){
- result.push_back(path);
- return;
- }
- //单层搜索逻辑
- for(int i=startIndex; i<candidates.size(); i++){
- path.push_back(candidates[i]);
- sum += candidates[i];
- backtracking(candidates, target, sum, i);
- //回溯,撤销删除
- sum -= candidates[i];
- path.pop_back();
- }
- return;
- }
- vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
- backtracking(candidates, target, 0, 0);
- return result;
- }
- };
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |