因为我们要利用Set的特性去重,所以需要加入这个变量Set<List<Integer>> set = new HashSet<>();,另外,为了保证顺序,我们再进行排序Arrays.sort(nums),这样能避免元素一样,但是顺序不一样的重复子集问题 。
所以,结果就出来了 。
List<List<Integer>> list = new ArrayList<>(); Set<List<Integer>> set = new HashSet<>(); public List<List<Integer>> subsetsWithDup(int[] nums) { if(nums.length == 0){ return null; } //排序 Arrays.sort(nums); List<Integer> temp = new ArrayList<>(); backTrace(0, nums, temp); return list; } public void backTrace(int start, int[] nums, List<Integer> temp){ //set去重操作 if(!set.contains(temp)){ set.add(new ArrayList<>(temp)); list.add(new ArrayList<>(temp)); } for(int j = start; j < nums.length; j++){ temp.add(nums[j]); backTrace(j+1,nums,temp); temp.remove(temp.size()-1); } }
看一下结果发现效率不是很好 。
文章插图
那我们再来看一下另外一种剪枝的策略用来去重 。
- 方法二:i > start && nums[i-1] == nums[i]
文章插图
所以,我们这种方法就可以做出来了 。
List<List<Integer>> list = new ArrayList<>(); public List<List<Integer>> subsetsWithDup(int[] nums) { if(nums.length == 0){ return null; } Arrays.sort(nums); List<Integer> temp = new ArrayList<>(); backTrace(0, nums, temp); return list; } public void backTrace(int start, int[] nums, List<Integer> temp){ list.add(new ArrayList<>(temp)); for(int i = start; i < nums.length; i++){ //剪枝策略 if(i > start && nums[i] == nums[i-1]){ continue; } temp.add(nums[i]); backTrace(i+1,nums,temp); temp.remove(temp.size()-1); } }
文章插图
哎呦,好像还可以哦 。
3 组合问题把前面的子集问题搞定之后,你会发现,后面的组合问题,排列问题就都不是什么大问题了,基本上都是套路了 。
推荐阅读
- 你需要知道的各种指针运算
- JavaScript中的for循环
- 复制宝贝怎么用 怎样复制别人店铺里面的宝贝
- 将32位Windows10升级到64位版本的方法,就是这么简单
- 茶香完美共融,重口味的男人茶
- 非常全面的网桥基础知识,只看这一篇文章就足够了
- eBay PB 级日志系统的存储方案实践
- 茶叶蛋的做法,茶叶蛋的危害
- 茶叶同翅目吸汁型害虫,日本出现新的茶树害虫
- 茶通用初制术语,黑茶初制与绿茶初制的区别