原题:
Given a set of distinct integers, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3], a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
分析:给定一个不重复的整数数组,要求由他的元素组成的所有子集合,即求一个集合的所有子集合
对于长度为n的集合,他的子集合有2^n个,证明很简单:每个元素要么出现在子集合中要么不出现在子集合中,故有两种选择,共有n个元素,所有一共有2^n种情况。
以[1,2,3]为例
0) 0 0 0 -> Don’t take 3 , Don’t take 2 , Dont take 1 = { }
1) 0 0 1 -> Don’t take 3 , Don’t take 2 , take 1 = {1 }
2) 0 1 0 -> Don’t take 3 , take 2 , Don’t take 1 = { 2 }
3) 0 1 1 -> Don’t take 3 , take 2 , take 1 = { 1 , 2 }
4) 1 0 0 -> take 3 , Don’t take 2 , Don’t take 1 = { 3 }
5) 1 0 1 -> take 3 , Don’t take 2 , take 1 = { 1 , 3}
6) 1 1 0 -> take 3 , take 2 , Don’t take 1 = { 2 , 3}
7) 1 1 1 -> take 3 , take 2 , take 1 = { 1 ,2 , 3 }
因此便有了以下思路:判断某位是0还是1,若是1则加入子集合,否则便不加入。
第一层循环2^n次,第二层循环n次,总的时间复杂度为O(n*2^n)
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
Arrays.sort(nums);
int totalNumber = 1 << nums.length;//子集合的个数
List<List<Integer>> collection = new ArrayList<List<Integer>>(totalNumber);
for (int i=0; i<totalNumber; i++) {
List<Integer> set = new LinkedList<Integer>();
for (int j=0; j<nums.length; j++) {
if ((i & (1<<j)) != 0) {//位运算判断位上是0还是1
set.add(nums[j]);
}
}
collection.add(set);
}
return collection;
}
}