Leetcode-Subsets II

LiBlog發表於2014-11-16

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],
  []
]
Have you met this question in a real interview?
 
Analysis:
We first create a table of (val,count) to record how many times each number appears in the collection. We then recursive create the subset for each number.
 
Solution:
 1 public class Solution {
 2     public List<List<Integer>> subsetsWithDup(int[] num) {
 3         List<List<Integer>> numList = new ArrayList<List<Integer>>();
 4         List<List<Integer>> res= new ArrayList<List<Integer>>();
 5         if (num.length==0) return res;
 6 
 7         for (int i=0;i<num.length;i++){
 8             int val = num[i];
 9             int index = -1;
10             boolean hasItem = false;
11             for (int j=0;j<numList.size();j++)
12                 if (numList.get(j).get(0)<val)
13                     continue;
14                 else if (numList.get(j).get(0)==val){
15                     hasItem = true;
16                     index = j;
17                     break;
18                 } else {
19                     index = j;
20                     break;
21                 }
22             if (hasItem)
23                 numList.get(index).set(1,numList.get(index).get(1)+1);
24             else if (index!=-1){
25                 List<Integer> temp = new ArrayList<Integer>();
26                 temp.add(val);
27                 temp.add(1);
28                 numList.add(index,temp);
29             } else {
30                 List<Integer> temp = new ArrayList<Integer>();
31                 temp.add(val);
32                 temp.add(1);
33                 numList.add(temp);
34             }
35         }
36         
37         res = subsetsRecur(numList,0);
38         return res;        
39     }
40 
41     public List<List<Integer>> subsetsRecur(List<List<Integer>> numList, int curIndex){
42         int val = numList.get(curIndex).get(0);
43         int num = numList.get(curIndex).get(1);
44         List<List<Integer>> resList = new ArrayList<List<Integer>>();
45         if (curIndex==numList.size()-1){            
46             for (int i=0;i<=num;i++){
47                 List<Integer> subset = new ArrayList<Integer>();
48                 for (int j=0;j<i;j++)
49                     subset.add(val);
50                 resList.add(subset);
51             }
52             return resList;
53         }
54 
55         List<List<Integer>> nextResList = subsetsRecur(numList,curIndex+1);
56 
57         for (int i=0;i<=num;i++){
58             List<Integer> subset = new ArrayList<Integer>();
59             for (int j=0;j<i;j++)
60                 subset.add(val);
61             for (int j=0;j<nextResList.size();j++){
62                 List<Integer> oneRes = new ArrayList<Integer>();
63                 oneRes.addAll(subset);
64                 oneRes.addAll(nextResList.get(j));
65                 resList.add(oneRes);
66             }
67         }
68         return resList;
69     }
70 }

NOTE: To increase runtime speed, we can sort the num list and then scan it once to create the table, like this:

 1 public class Solution {
 2     public List<List<Integer>> subsetsWithDup(int[] num) {
 3         List<List<Integer>> numList = new ArrayList<List<Integer>>();
 4         List<List<Integer>> res= new ArrayList<List<Integer>>();
 5         if (num.length==0) return res;
 6 
 7         Arrays.sort(num);
 8         int curVal = num[0];
 9         int count = 1;
10         for (int i=1;i<num.length;i++)
11             if (num[i]==curVal){
12                 count++;
13             } else {
14                 List<Integer> record = new ArrayList<Integer>();
15                 record.add(curVal);
16                 record.add(count);
17                 numList.add(record);
18                 curVal = num[i];
19                 count=1;
20             }
21         List<Integer> record = new ArrayList<Integer>();
22         record.add(curVal);
23         record.add(count);
24         numList.add(record);
25         
26         
27         res = subsetsRecur(numList,0);
28         return res;        
29     }
30 
31     public List<List<Integer>> subsetsRecur(List<List<Integer>> numList, int curIndex){
32         int val = numList.get(curIndex).get(0);
33         int num = numList.get(curIndex).get(1);
34         List<List<Integer>> resList = new ArrayList<List<Integer>>();
35         if (curIndex==numList.size()-1){            
36             for (int i=0;i<=num;i++){
37                 List<Integer> subset = new ArrayList<Integer>();
38                 for (int j=0;j<i;j++)
39                     subset.add(val);
40                 resList.add(subset);
41             }
42             return resList;
43         }
44 
45         List<List<Integer>> nextResList = subsetsRecur(numList,curIndex+1);
46 
47         for (int i=0;i<=num;i++){
48             List<Integer> subset = new ArrayList<Integer>();
49             for (int j=0;j<i;j++)
50                 subset.add(val);
51             for (int j=0;j<nextResList.size();j++){
52                 List<Integer> oneRes = new ArrayList<Integer>();
53                 oneRes.addAll(subset);
54                 oneRes.addAll(nextResList.get(j));
55                 resList.add(oneRes);
56             }
57         }
58         return resList;
59     }
60 }

 

相關文章