LeetCode-Subsets

题目:https://oj.leetcode.com/problems/subsets/

Given a set of distinct integers, 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,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;
	}
}

你可能感兴趣的:(LeetCode)