LeetCode90求集合的所有子集,集合是可以重复的

题目

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);
	    }

}

这个时间是最短的。

你可能感兴趣的:(leetcode)