【leetcode】40Combination Sum II(回溯方法)
来源:互联网 发布:latex mac版 编辑:程序博客网 时间:2024/04/29 16:38
题目大意:
给出一个候选数字集(其中可能有重复的数字),还有一个目标数字,数字均为正整数,从候选数字集中选取数字,候选集中每个元素最多选一次(若相同数字有多个则可多次选取),要求输出所有满足和为目标数的不重复的方案。
例子:候选集为[10, 1, 2, 7, 6, 1, 5],目标值为8
结果为
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
思路:
1.首先应对候选数字集进行排序,可使相同数字相邻,且方便后续剪枝
2.为了保证输出的方案不重复,应仔细考虑有重复数字的情况,这也是这道题的重点:
比较容易想出的方法是先对于重复的数字计数,再继续考虑选择0个至cnt个的情况,基于这种思想是下面的代码1
看了讨论区得到的另一种思路是,对于相同元素,每次都选择前面的
(例如有三个相同的数字,用1表示选择,0表示不选择,000,100,110,111代表了所有不重复的情况,则000,1xx已经包含所有情况。
代码2中先在tmp中加入了candidates[i],然后BackTracking(candidates,target-candidates[i],i+1,tmp,ans))即是1xx这种情况,
对于000这种情况,这份代码中没有显式调用BackTracking(candidates,target,i+1,tmp,ans)),而是跳过后序重复元素后进入下一次循环,新的一次循环中只有i的值改变了,其效果与显式调用相同
方法一:16ms
class Solution {public: void combination(vector<int>&candidates,int target,int pos,vector<int>&tmp,vector<vector<int>>&ans) { if(target==0) { ans.push_back(tmp); return; } int n=candidates.size(); if(pos>=n) return; int x=candidates[pos]; int cnt=1; while((pos+cnt<n)&&candidates[pos+cnt]==x) ++cnt; //对重复的数字计数 int i; for(i=0;i<=cnt;++i) //针对选择0个至cnt个元素分别调用函数 { if(i*x<=target) { combination(candidates,target-i*x,pos+cnt,tmp,ans); tmp.push_back(x); } else break; } for(int j=1;j<=i;++j) tmp.pop_back(); //回溯 } vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(),candidates.end()); vector<vector<int>> ans; vector<int>tmp; combination(candidates,target,0,tmp,ans); return ans; }};
方法二:8ms
class Solution {public: void BackTracking(vector<int>&candidates,int target,int pos,vector<int>&tmp,vector<vector<int>>&ans) { if(target==0) ans.push_back(tmp); else { int n=candidates.size(); for(int i=pos;i<n&&candidates[i]<=target;++i) { tmp.push_back(candidates[i]); BackTracking(candidates,target-candidates[i],i+1,tmp,ans); //选择了candidates[i]的情况 tmp.pop_back(); while(i+1<n&&candidates[i]==candidates[i+1]) ++i; //选择了重复数字的情况已在上面包含,这里需要略去相同数字 } } } vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(),candidates.end()); vector<vector<int>> ans; vector<int>tmp; //临时存储当前组合 BackTracking(candidates,target,0,tmp,ans); return ans; }};
0 0
- 【leetcode】40Combination Sum II(回溯方法)
- [leetcode][回溯] Combination Sum II
- (回溯法)LeetCode#40. Combination Sum II
- leetcode Combination Sum II回溯问题
- Leetcode|Combination Sum II[递归回溯]
- leetcode 40. Combination Sum II-回溯算法
- leetcode 216 Combination Sum II (回溯法)
- LeetCode(40) Combination Sum II
- LeetCode(40)--Combination Sum II
- [leetcode][回溯] Combination Sum
- LeetCode(40) Combination Sum II
- [leetcode 40] Combination Sum II
- leetcode || 40、Combination Sum II
- leetcode 40: Combination Sum II
- Leetcode #40 Combination Sum II
- LeetCode(40) Combination Sum II
- LeetCode-40 Combination Sum II
- LeetCode 40: Combination Sum II
- 工厂方法(一)
- 插件框架一之主工程Application中theme使用主工程资源问题
- 类的定义
- android:关于自定义不能滑动的ViewPager后在使用View加载其所在的的布局时报错:Error inflating class view.NoscrollViewPager
- 区间最大频率
- 【leetcode】40Combination Sum II(回溯方法)
- HDU5745 La Vie en rose
- Git命令小总结
- Java---replace与replaceAll的区别
- 插件框架一之解决插件布局自定义组件无法使用问题
- 插件框架一之三星ContentView报错bug
- JS笔记5-Ajax基础
- 插件框架一之Android5.0非正式版rom插件中new WebView报错
- 堆栈