package com.example.lettcode.dailyexercises;
import java.util.*;
/**
* @Class SubsetsWithDup
* @Description 90 子集II
* 给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
* 解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
* <p>
* 示例 1:
* 输入:nums = [1,2,2]
* 输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
* <p>
* 示例 2:
* 输入:nums = [0]
* 输出:[[],[0]]
* @Author
* @Date 2021/3/31
**/
public class SubsetsWithDup {
/**
* 方法1:回溯算法
* 和子集I不同的是,子集II可能出现重复的情况,所以需要去重
* @param nums
* @return
*/
public static List<List<Integer>> subsetsWithDup(int[] nums) {
if (nums == null || nums.length == 0) return new ArrayList<>();
// 去重
Set<List<Integer>> resSet = new HashSet<>();
resSet.add(new ArrayList<>());
for (int i = 0; i < nums.length; i++) {
List<List<Integer>> listList = new ArrayList<>();
for (List<Integer> integerList : resSet) {
// 不能直接在List上修改需要复制一份
List<Integer> integers = new ArrayList<>(integerList);
integers.add(nums[i]);
// 排序去重
Collections.sort(integers);
listList.add(integers);
}
resSet.addAll(listList);
}
List<List<Integer>> resList = new ArrayList<>();
for (List<Integer> integers : resSet) {
resList.add(integers);
}
return resList;
}
}
// 测试用例
public static void main(String[] args) {
int[] nums = new int[]{1, 2, 2};
List<List<Integer>> listList = subsetsWithDup(nums);
System.out.print("SubsetsWithDup demo01 result:[");
for (List<Integer> integerList : listList) {
System.out.print("[");
for (Integer integer : integerList) {
System.out.print("," + integer);
}
System.out.print("]");
}
System.out.println("]");
nums = new int[]{0};
listList = subsetsWithDup(nums);
System.out.print("SubsetsWithDup demo02 result:[");
for (List<Integer> integerList : listList) {
System.out.print("[");
for (Integer integer : integerList) {
System.out.print("," + integer);
}
System.out.print("]");
}
System.out.println("]");
nums = new int[]{4, 4, 4, 1, 4};
listList = subsetsWithDup(nums);
System.out.print("SubsetsWithDup demo03 result:[");
for (List<Integer> integerList : listList) {
System.out.print("[");
for (Integer integer : integerList) {
System.out.print("," + integer);
}
System.out.print("]");
}
System.out.println("]");
}