题目:https://oj.leetcode.com/problems/subsets/
Given a set of distinct integers, S, return all possible subsets.
Note:
For example,
If S = [1,2,3]
, a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
方法1、增量构造法
分析:对每个元素,都有两种选择,选或者不选。源码:Java版本
算法分析:增量构造法,深搜,时间复杂度O(2^n),空间复杂度O(n)
public class Solution { public List<List<Integer>> subsets(int[] S) { Arrays.sort(S); //sort List<List<Integer>> results = new ArrayList<List<Integer>>(); Stack<Integer> path = new Stack<Integer>(); subsets(S,path,0,results); return results; } @SuppressWarnings("unchecked") public void subsets(int[] S, Stack<Integer> path, int step, List<List<Integer>> results) { if(step==S.length) { results.add((Stack<Integer>)(path.clone())); return; } subsets(S,path,step+1,results); path.push(S[step]); subsets(S,path,step+1,results); path.pop(); } }
方法2、 二进制法
分析:本方法的前提是:集合的元素不超过int 位数。用一个int 整数表示位向量,第i 位为1,则表示选择S[i],为0 则不选择。例如S={A,B,C,D},则0110=6 表示子集{B,C}。
这种方法最巧妙。因为它不仅能生成子集,还能方便的表示集合的并、交、差等集合运算。设两个集合的位向量分别为B1 和B2,则B1 [ B2;B1 \ B2;B1△B2 分别对应集合的并、交、对称差。二进制法,也可以看做是位向量法,只不过更加优化。
源码:Java版本
算法分析:二进制法,时间复杂度O(2^n),空间复杂度O(1)
public class Solution { public static List<List<Integer>> subsets(int[] S) { Arrays.sort(S); List<List<Integer>> results = new ArrayList<List<Integer>>(); int len=S.length; for(int i=0;i<(1<<len);i++) { List<Integer> path = new ArrayList<Integer>(); for(int j=0;j<len;j++) { if(((1<<j)&i)!=0) { path.add(S[j]); } } results.add(path); } return results; } }