问题
Given an integer array nums, return all possible subsets (the power set).
The solution set must not contain duplicate subsets.
Example 1:
Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
Example 2:
Input: nums = [0]
Output: [[],[0]]
Constraints:
- 1 <= nums.length <= 10
- -10 <= nums[i] <= 10
方法1
从空开始,每次从原始数组中选出一个数字的时候都有两个选择, 把这个加入已经存在的数字list, 或者不加入.
时间复杂度
O
(
n
∗
2
n
)
O(n* 2^n)
O(n∗2n).
空间复杂度
O
(
n
∗
2
n
)
O(n* 2^n)
O(n∗2n)
class Solution {
public List<List<Integer>> subsets(int[] nums) {
return helper(nums, nums.length -1);
}
private List<List<Integer>> helper(int[] nums, int n){
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(n >= 0){
for(List<Integer> list : helper(nums, n - 1)){
result.add(list);
ArrayList<Integer> temp = (ArrayList<Integer>) ((ArrayList)list).clone();
temp.add(nums[n]);
result.add(temp);
}
} else
result.add(new ArrayList<Integer>());
return result;
}
}
方法2
首先要得是subset, 也就是最后得到的结果集中,数字之间的顺序不重要, 重要的是内容.
然后数字最多只有10个, 那么可以直接用10位2进制数来表示在结果集中某个数字是否存在.
时间复杂度
O
(
n
∗
2
n
)
O(n* 2^n)
O(n∗2n).
空间复杂度
O
(
n
∗
2
n
)
O(n* 2^n)
O(n∗2n).
class Solution {
public List<List<Integer>> subsets(int[] nums) {
// 数组长度
int len = nums.length;
// 起始数字(包括)是n个0,终止数字(不包括)是n+1个0
int start = 1<<len, end = 1<<(len + 1);
List<List<Integer>> res = new ArrayList<List<Integer>>();
for (int i = start; i < end; i++) {
// 第一位是1, 所以要去掉
String bitmap = Integer.toBinaryString(i).substring(1);
int size = bitmap.length();
List<Integer> cur = new ArrayList<Integer>(size);
// 对二进制数每一位进行判断,如果值为1,视为当前位置代表的数字在结果集中
for (int j = 0; j < size; j++)
if (bitmap.charAt(j) == '1')
cur.add(nums[j]);
res.add(cur);
}
return res;
}
}