LeetCode: Subsets & Subsets II

Given a set of distinct integers, S, return all possible subsets.

我想到的算法是这个样子的。我想用的是递归。n个数的subset可以由n-1个数的subset产生。

就是把subset(n-1)以及其中每一个组合加上S[n]。比如[1,2,3] = [], [1], [2], [1,2], []+3, [1]+3, [2]+3, [1, 2]+3;

 1 public static ArrayList<ArrayList<Integer>> subsets(int[] S, int aa) {
 2         if(aa == 0) {
 3             return new ArrayList<ArrayList<Integer>>();
 4         }
 5         else if(aa == 1) {
 6             ArrayList<ArrayList<Integer>> a = new ArrayList<ArrayList<Integer>>();
 7             ArrayList<Integer> t1 = new ArrayList<Integer>();
 8             t1.add(S[0]);
 9             a.add(t1);
10             a.add(new ArrayList<Integer>());
11             return a;
12         }
13         else {
14             ArrayList<ArrayList<Integer>> Q = new ArrayList<ArrayList<Integer>>();
15             ArrayList<ArrayList<Integer>> R = new ArrayList<ArrayList<Integer>>();
16             for (ArrayList<Integer> x : subsets(S, aa-1)) {
17                 Q.add(x);
18             }
19             
20             R.addAll(Q);
21             for (ArrayList<Integer> x : Q) {
22             ArrayList<Integer> y = new ArrayList<Integer>(x);
23             y.add(S[aa-1]);
24             R.add(y);
25             }
26             return R;
27         }

 

又学习到一种DFS的方法。[1,2,3,4]的subsets的第一个元素可以是1, 2, 3, 4. 如果第一个是1,那么第二个可是是2,3,4. 第三个可以是第二个元素之后的数。

所以就是先是1,然后是1,2,然后1,2,3,然后1,2,3,4,然后4后面没得选了;回溯到3,上一次3后面选的是4,但是没有其他可以选的了,回溯到2. 2上一次选的是3,这一次课一选4.。。。。。。。

 1 public static ArrayList<ArrayList<Integer>> subsets2(int[] S) {  
 2            ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();  
 3            ArrayList<Integer> tmp = new ArrayList<Integer>();  
 4            Arrays.sort(S);  
 5            res.add(tmp);  
 6            dfs(res,tmp,S,0);  
 7            return res;  
 8         }  
 9           
10     public static void dfs(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> tmp, int[] S, int pos){  
11           for(int i=pos; i<S.length;i++) {
12               tmp.add(S[i]);  
13               res.add(new ArrayList<Integer>(tmp));  
14               dfs(res,tmp,S,i+1);  
15               tmp.remove(tmp.size()-1);  
16           }  
17     } 

 


Given a collection of integers that might contain duplicates, S, return all possible subsets.

这一次包含重复元素。按照上面第一种方法,就得到一个组合之后看看result里有没有,如果没有就包含进去。

 1 public static ArrayList<ArrayList<Integer>> subsetsWithDup(int[] num) {
 2         Arrays.sort(num);
 3         return subsets(num, num.length);
 4     }
 5     public static ArrayList<ArrayList<Integer>> subsets(int[] S, int aa) {
 6         if(aa == 0) {
 7             return new ArrayList<ArrayList<Integer>>();
 8         }
 9         else if(aa == 1) {
10             ArrayList<ArrayList<Integer>> a = new ArrayList<ArrayList<Integer>>();
11             ArrayList<Integer> t1 = new ArrayList<Integer>();
12             t1.add(S[0]);
13             a.add(t1);
14             a.add(new ArrayList<Integer>());
15             return a;
16         }
17         else {
18             ArrayList<ArrayList<Integer>> Q = new ArrayList<ArrayList<Integer>>();
19             ArrayList<ArrayList<Integer>> R = new ArrayList<ArrayList<Integer>>();
20             for (ArrayList<Integer> x : subsets(S, aa-1)) {
21                 Q.add(x);
22             }
23             
24             R.addAll(Q);
25             for (ArrayList<Integer> x : Q) {
26             ArrayList<Integer> y = new ArrayList<Integer>(x);
27             y.add(S[aa-1]);
28             if (!R.contains(y))
29                 R.add(y);
30             }
31             return R;
32         }

 

用dfs的话,就在回溯的时候判断上一次使用的下一个元素和当前的时候一样,如果一样的话就跳过。这种方法因为不用经常在ArrayList里查找,因此速度会快一点。

 1 public static ArrayList<ArrayList<Integer>> subsets2(int[] S) {  
 2            ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();  
 3            ArrayList<Integer> tmp = new ArrayList<Integer>();  
 4            Arrays.sort(S);  
 5            res.add(tmp);  
 6            dfs(res,tmp,S,0);  
 7            return res;  
 8         }  
 9           
10     public static void dfs(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> tmp, int[] S, int pos){  
11           for(int i=pos; i<S.length;i++) {
12               tmp.add(S[i]);  
13               res.add(new ArrayList<Integer>(tmp));  
14               dfs(res,tmp,S,i+1);  
15               tmp.remove(tmp.size()-1); 
16               while (i<S.length-1 && S[i+1] == S[i]) i++;
17           }  
18     } 

 

posted on 2014-01-21 03:45  longhorn  阅读(254)  评论(0编辑  收藏  举报

导航