【leetcode刷题笔记】Subsets II

Given a collection of integers that might contain duplicates, S, 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 S = [1,2,2], a solution is:

[

  [2],

  [1],

  [1,2,2],

  [2,2],

  [1,2],

  []

]

subsets这道题非常相像,除了S中会有重复的元素,那么会有什么影响呢?看一个例子:

S = [1,1]

根据subsets中的算法,生成的子集如下:

[

  [],

  [1],

  [1],

  [1,1]

]

显然[1],[1]这两个是重复的,需要去掉。那么我们怎么判重?只需要在递归函数的循环里面加上如下判断

 if(i != pos && s[i] == s[i - 1]) continue; 就可以了。

理解这个判断的关键,是搞清楚递归函数

public void subsetsDfs(int[] s,int level,int pos,ArrayList<Integer> result,List<List<Integer>> answer)

中pos变量的含义。

在这个函数中,level表示要生成的子集的长度,pos则表示目前要生成子集的第pos位上的元素。那么当i==pos的时候,说明子集中第pos位上的元素还没有生成过,那么即使s[i]==s[i-1],它们在生成的子集中所占有的位置不同(例如例子中的[1,1]中的两个1分别在生成的子集的第0位和第1位上),s[i]就可以加到这个子集上去。但是当i != pos的时候,说明生成的子集上第pos位已经有元素了,如果当前的s[i]和这个元素s[i-1]相等,那么就没有必要再在这个位置上重复放置s[i]了(例如上述例子中已经有子集[1]的时候,不能够再生成子集[s[1]=1]了)。

最后实现的代码如下:

 1 public class Solution {

 2     public void subsetsDfs(int[] s,int level,int pos,ArrayList<Integer> result,List<List<Integer>> answer){

 3         if(result.size() == level){

 4             answer.add(new ArrayList<Integer>(result));

 5             return;

 6         }

 7         for(int i = pos;i < s.length;i++){

 8             if(i != pos && s[i] == s[i - 1])

 9                 continue;                

10             result.add(s[i]);

11             subsetsDfs(s, level, i+1, result, answer);

12             result.remove(result.size()-1);

13         }

14     }

15     public List<List<Integer>> subsetsWithDup(int[] S) {

16         Arrays.sort(S);

17         List<List<Integer>> answer = new ArrayList<List<Integer>>();

18         ArrayList<Integer> result = new ArrayList<Integer>();

19         

20         for(int i = 0;i <= S.length;i++)

21             subsetsDfs(S, i, 0, result, answer);

22         return answer;

23     }

24 }

你可能感兴趣的:(LeetCode)