题目
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).
Note: 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], [] ]
因为可以重复,所以首先应该进行排序,Arrays.sort()函数,我以前没用过,现在知道有这样的一个函数了,但是我自己的写的冒泡排序比这个快,不知道为啥呀。
首先,看看我的两个逻辑,其实依赖map函数有点儿费时:
package leetcode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LC90SubSetsII {
public static List> subsetsWithDup(int[] nums) {
List> ret = new ArrayList>();
Map map = new HashMap();
int len = nums.length;
if(len == 0){
return ret;
}
Arrays.sort(nums);//两种排序的对比
/*for(int i = 0;i temp = ret.get(j);
List list = new ArrayList();
String str = "";
for(int k=0;k< temp.size();k++){
list.add(temp.get(k));
str=str+temp.get(k);
}
list.add(nums[i]);
str=str+nums[i];
if(map.containsKey(str)){
continue;
}
map.put(str, 1);
ret.add(list);
}
List list = new ArrayList();
if(map.containsKey(String.valueOf(nums[i]))){
continue;
}
map.put(String.valueOf(nums[i]), 1);
list.add(nums[i]);
ret.add(list);
}
List list = new ArrayList();
ret.add(list);
return ret;
}
public static void main(String[] args) {
int[] nums={2,2,1,2};
List> list = subsetsWithDup(nums);
for(int i =0;i
于是就又想了个办法,不用map的既然都排好序了,那么相同的必定都挨在一起了;对于相同的来说,只能增加包含这个数字的集合的基础上再次的增加这个数。于是具体代码如下:
package leetcode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LC90SubSetsIV {
public static List> subsetsWithDup(int[] nums) {
List> ret = new ArrayList>();
Map map = new HashMap();
int len = nums.length;
if(len == 0){
return ret;
}
Arrays.sort(nums);
List> lastlist = new ArrayList>();
for(int i=0;i0 && nums[i]==nums[i-1]){//相同的情况
List> lastdata = new ArrayList>(lastlist);//但我估计这个费时就废在这段了
int l=lastdata.size();
lastlist.clear();//清空,为的就只保留增加的。
for(int j=0;j temp = lastdata.get(j);
List list = new ArrayList(temp);
list.add(nums[i]);
ret.add(list);
lastlist.add(list);
}
}else{
lastlist.clear();
for(int j=0;j temp = ret.get(j);
List list = new ArrayList(temp);
list.add(nums[i]);
ret.add(list);
lastlist.add(list);
}
List list = new ArrayList();
if(map.containsKey(String.valueOf(nums[i]))){
continue;
}
map.put(String.valueOf(nums[i]), 1);
list.add(nums[i]);
ret.add(list);
lastlist.add(list);
}
}
List list = new ArrayList();
ret.add(list);
return ret;
}
public static void main(String[] args) {
int[] nums={2,2,1,3};
List> list = subsetsWithDup(nums);
for(int i =0;i
下面就是递归的办法,这个时间是最短的,我暂时估计是因为地址指针的使用:
package leetcode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LC90SubSetsV {
public List> subsetsWithDup(int[] nums) {
List> result = new ArrayList>();
if (nums == null || nums.length == 0) {
return result;
}
Arrays.sort(nums);
helper(result, new ArrayList(), nums, 0);
return result;
}
private void helper(List> result, List cur, int[] nums, int index) {
if (nums.length == index) {
result.add(new ArrayList(cur));
return;
}
cur.add(nums[index]);//要了这个数字
helper(result, cur, nums, index + 1);
cur.remove(cur.size() - 1);//和不要这个数字
while (index + 1 < nums.length && nums[index + 1] == nums[index]) {
index++;
}
helper(result, cur, nums, index + 1);
}
}
这个时间是最短的。