题目
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,2], a solution is:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
题目大意:还是找到一个集合的所有子集,只是这个集合中有重复的元素。
思路
有了上篇的思路之后,这个题目基本一样,只是要用java中的Set容器对重复的结果进行过滤一下,就OK了。
相比上篇博文,只做了少量的修改。
实现代码如下:
public class Solution {
//模拟二进制加1
public boolean increment(int []arr){
int len=arr.length;
arr[len-1]++;//最低位加1
for(int i=len-1;i>=0;i--){
if(arr[i]>=2){
if(i==0){//最高位产生了进位,则已经变为了全一,结束
return false;
}
else{//
arr[i]-=2;
arr[i-1]++;
}
}
}
return true;
}
//nums中有重复的数字
public List<List<Integer>> subsetsWithDup(int[] nums) {
if(nums==null||nums.length<1){
return null;
}
//先进行排序
Arrays.sort(nums);
//开辟一个与nums长度相同的标志数组,并初始化为零
int len=nums.length;
int arr[]=new int[len];
for(int i=0;i<len;i++){
arr[i]=0;
}
Set<List<Integer>> s=new HashSet<List<Integer>>();
//定义一个List来保存结果
List<List<Integer>> resultList=new ArrayList<List<Integer>>();
s.add(new ArrayList<Integer>());
//resultList.add(new ArrayList<Integer>());//将空集加入
while(increment(arr)){//模拟二进制加一
List<Integer> list=new ArrayList<Integer>();//
for(int i=0;i<len;i++){
if(arr[i]==1){//arr中标志位1时,nums的相应元素参与了组合
list.add(nums[i]);
}
}
s.add(list);
//resultList.add(list);
}
for(List<Integer> l:s){
resultList.add(l);
}
return resultList;
}
}
AC结果如下: