描述
给定一个可能具有重复数字的列表,返回其所有可能的子集。
- 子集中的每个元素都是非降序的
- 两个子集间的顺序是无关紧要的
- 解集中不能包含重复子集
样例
样例 1:
输入:
nums = [0]
输出:
[
[],
[0]
]
解释:[0]的子集只有[]和[0]。
样例 2:
输入:
nums = [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
解释:[1,2,2]不重复的子集有[],[1],[2],[1,2],[2,2],[1,2,2]。
和子集的区别在于多了重复的元素,采用集合中的方法判断重复的元素即可。
public class Solution {
public static List<List<Integer>> subsetsWithDup(int[] nums) {
// 边界
List<List<Integer>> list = new ArrayList<>();
if (nums==null||nums.length==0){
List<Integer> list1 = new ArrayList<>();
list.add(list1);
return list;
}
if(nums.length==1){
List<Integer> temp1 = new ArrayList<>();
list.add(temp1);
List<Integer> temp2 = new ArrayList<>();
temp2.add(nums[0]);
list.add(temp2);
return list;
}
Arrays.sort(nums);
List<Integer> listTemp = new ArrayList<>();
for (int i = 0; i < nums.length+1 ; i++) {
helper(nums,i,list,listTemp,0);
}
// 递归处理非边界
return list;
}
public static void helper(int[] nums,int k,List<List<Integer>> list,List<Integer> listTemp,int start){
if (listTemp.size()==k){
List<Integer> temp = new ArrayList<>();
for (int i = 0; i < k; i++) {
temp.add(listTemp.get(i));
}
if (list.contains(temp)) return;
list.add(temp);
return;
}
for (int i = start; i < nums.length; i++) {
listTemp.add(nums[i]);
helper(nums,k,list,listTemp,i+1);
listTemp.remove(listTemp.size()-1);
}
}
}