带重复元素的子集

给定一个可能具有重复数字的列表,返回其所有可能的子集

 注意事项
  • 子集中的每个元素都是非降序的
  • 两个子集间的顺序是无关紧要的
  • 解集中不能包含重复子集
样例

如果 S = [1,2,2],一个可能的答案为:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

思路:

第一种做法,递归加回溯。同一层中只要不选相同的数字,那么就不会出现重复的情况。(看似很有道理,可是证明它的正确性貌似没有这么容易,如何想到这种策略的呢?)

第二种做法,二进制加速(厉害了),利用hashset中不能包含相同的元素的特点,HashSet<arraylist> ans ,这样的结构为最后结果。
5个数字就有2的5次方种子集(不考虑重复),每一种情况就是一个数字,这个数字二进制表示的时候,有1的位要,为0的位不要。

 

第一种做法略

第二种做法:

import java.util.*;
class Solution {
    /**
     * @param S: A set of numbers.
     * @return: A list of lists. All valid subsets.
     */
    public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] S) {
        // write your code here
        Arrays.sort(S);
        HashSet<ArrayList<Integer>> ans=new HashSet<ArrayList<Integer>>();
        int len=S.length;
        for(int i=0;i<Math.pow(2,len);i++){
            ArrayList<Integer> temp=new ArrayList<Integer>();
            int tem=i;
            for(int j=0;j<len;j++){
                int tempint=tem&1;
                if(tempint==1){
                    temp.add(S[j]);
                }
                tem>>=1;
            }
            ans.add(temp);
        }
        return new ArrayList<ArrayList<Integer>>(ans);
    }
}

 

posted @ 2016-11-24 23:06  萝卜er  阅读(558)  评论(0编辑  收藏  举报