Java求解子集II

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java求解子集II相关的知识,希望对你有一定的参考价值。

一、题目

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

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

二、题解

该题和 求组合总和II 类似,也就是在上一题的基础上增加了去重。

去重套路就是加一个标志数组,在树层去重;

用示例中的[1, 2, 2] 来举例,如图所示:(注意去重需要先对集合排序)

从图中可以看出,同一树层上重复取2 就要过滤掉,同一树枝上就可以重复取2,因为同一树枝上元素的集合才是唯一子集!

其他步骤分析依照回溯三部曲即可

三、代码

class Solution 
    List<List<Integer>> lists = new ArrayList<>();
    Deque<Integer> deque = new LinkedList<>();

    public List<List<Integer>> subsetsWithDup(int[] nums) 
        // 首先排序,保证相同的数字紧挨着,方便依次判断
        Arrays.sort(nums);
        // 标志数组,用来排除统一树层的后续节点不在访问
        boolean[] flag = new boolean[nums.length];
        backTracking(nums, 0, flag);
        return lists;
    

    public void backTracking(int[] nums, int index, boolean[] flag) 
        lists.add(new ArrayList(deque));
        // 同样这里的递归终止条件不写也可以,for循环也会进行终止
        if (index >= nums.length) 
            return;
        
        for (int i = index; i < nums.length; i++) 
            // 排除后续同一树层节点不在访问
            if (i > 0 && nums[i] == nums[i - 1] && !flag[i - 1]) 
                continue;
            
            flag[i] = true;
            deque.addLast(nums[i]);
            backTracking(nums, i + 1, flag);
            deque.removeLast();
            flag[i] = false;
        
    

四、总结

以上是关于Java求解子集II的主要内容,如果未能解决你的问题,请参考以下文章

java 90.子集II.java

java 90.子集II.java

java 90.子集II.java

java 90.子集II.java

java 90.子集II.java

java 90.子集II.java