码迷,mamicode.com
首页 > 其他好文 > 详细

90.子集Ⅱ

时间:2021-06-15 17:58:02      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:void   int   oid   src   for   blog   str   https   正数   

90.子集Ⅱ

题目

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

示例 1:

输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:

输入:nums = [0]
输出:[[],[0]]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subsets-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

这道题和78.子集的区别在于正数数组中可能包含重复的元素。

39.组合总和与40.组合总和Ⅱ有一定的参考价值。先借鉴对整数数组进行排序的方法,来画图。

技术图片

总结之前的思路
1.对整数数组进行排序,方便剪枝。剪枝思路是同一层同一个元素只能出现一次。
2.递归从上往下,每一个节点都需要返回,把path加入结果集应该写在回溯函数的最前面。

题解

Arrays.sort(nums); 先排序!!

递归的参数和返回值
nums:输入数组
startIndex:对同一集合进行组合,需要使用startIndex来标记起始区间

List<List<Integer>> res;
List<Integer> path;

void backtracing(int[]nums,int startIndex);

递归的终止条件
这里的思路与78相同,for循环把数组nums从头取到尾,i<nums.length
递归的层数是不确定的,终止条件也是取到数组的末尾,也就是startIndex>=nums.length

startIndex >= nums.length时,i也是大于nums.length是不会进入循环说明这次递归结束,所以这个条件也可以省略。

单层递归逻辑

同一层的同一个元素不能重复,排序之后,同一个元素应该挨着。那么nums[i] == nums[i-1]来判断是不是重复元素。
取值区间从startIndex开始,i == startIndex时说明是取值的第一个元素,那他应该直接加入路径并且之前的元素不能取。使用i>startIndex来控制。

    void backtracing(int[]nums,int startIndex){
       res.add(new ArrayList(path));
       for(int i = startIndex;i<nums.length;i++)
       {
           if(i>startIndex&&nums[i] == nums[i-1])continue;
           path.add(nums[i]);
           backtracing(nums,i+1);
           path.remove(path.size()-1);
       }
    }

90.子集Ⅱ

标签:void   int   oid   src   for   blog   str   https   正数   

原文地址:https://www.cnblogs.com/rananie/p/14883519.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!