题目
给你一个整数数组 nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
解法一
思路
- 扩展法 每次都往上一次得到的子集中追加一个元素。比如:
步骤 | 结果 | 备注 |
---|---|---|
初始 | [] | |
加入1 | [1] | 往上面的空集合中加入1 |
加入2 | [2] [1,2] | 往上面的[]和[1]中分别加入2 |
加入3 | [3] [1,3] [2,3] [1,2,3] |
代码
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
res.add(new LinkedList<>());
for (int num : nums) {
List<List<Integer>> temp = new LinkedList<>();
for (List<Integer> old : res) {
List<Integer> list = new LinkedList<>(old);
list.add(num);
temp.add(list);
}
for (List<Integer> list : temp) {
res.add(list);
}
}
return res;
}
update20220613
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
res.add(new LinkedList<>());
for (int num : nums) {
List<List<Integer>> temp = new LinkedList<>(res);
for (List<Integer> list : temp) {
List<Integer> l = new LinkedList<>(list);
l.add(num);
res.add(l);
}
}
return res;
}
解法二
思路
- 回溯法
代码
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
res.add(new LinkedList<>());
for (int len = 1; len <= nums.length; len++) {
backtracking(nums, res, 0, len, new LinkedList<>());
}
return res;
}
private void backtracking(int[] nums, List<List<Integer>> res, int index, int len, List<Integer> sub) {
if (sub.size() == len) {
res.add(new LinkedList<>(sub));
return;
}
for (int i = index; i < nums.length; i++) {
sub.add(nums[i]);
backtracking(nums, res, i + 1, len, sub);
sub.remove(sub.size() - 1);
}
}
解法三
思路
- dfs
代码
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
dfs(nums, res, 0, new LinkedList<>());
return res;
}
private void dfs(int[] nums, List<List<Integer>> res, int index, List<Integer> sub) {
res.add(new LinkedList<>(sub));
for (int i = index; i < nums.length; i++) {
sub.add(nums[i]);
dfs(nums, res, i + 1, sub);
sub.remove(sub.size() - 1);
}
}