第90题.子集II

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

说明:解集不能包含重复的子集。

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

思路

做本题之前一定要先做78.子集 (opens new window)

这道题目和回溯算法:求子集问题! (opens new window)区别就是集合里有重复元素了,而且求取的子集要去重。

那么关于回溯算法中的去重问题,在40.组合总和II (opens new window)中已经详细讲解过了,和本题是一个套路。

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

90.子集II

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

 

class Solution {
    List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
   LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
   boolean[] used;
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        if (nums.length == 0){
            return result;
        }
        Arrays.sort(nums);
        used = new boolean[nums.length];
        process(nums, 0);
        return result;
    }
    
    private void process(int[] nums, int startIndex){
        result.add(new ArrayList<>(path));
        if (startIndex == nums.length){
            return;
        }
        for (int i = startIndex; i < nums.length; i++){
            if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){
                continue;
            }
            path.add(nums[i]);
            used[i] = true;
            process(nums, i + 1);
            path.removeLast();
            used[i] = false;
        }
    }
}

  

 

  

 

posted @ 2021-09-21 10:16  sherry001  阅读(17)  评论(0编辑  收藏  举报