给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
(1)方法:遍历法
思路:先添加一个空链表到结果集中,然后遍历数组将每个数字都依次添加到结果集中当前子集,生成新的子集添加到结果集。
1,添加空链表到结果集;
2,将每个数字添加到结果集的所有子集,组成新的子集添加到结果集;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
//将遍历的当前数字加到每一个子集上,生成新的子集
List<List<Integer>> res = new ArrayList<>();
//需要先添加一个空链表子集
res.add(new ArrayList<>());
sub1(nums,res);
return res;
}
//遍历添加
private void sub1(int[] nums,List<List<Integer>> res) {
//遍历数组
for (int n : nums) {
//每个子集添加当前数字,然后生成新子集
int size = res.size();//取得当前的结果自己个数
for (int i = 0; i < size; i ++) {
List<Integer> sub = new ArrayList(res.get(i));
sub.add(n);
res.add(sub);
}
}
}
}
(2)递归回溯法
思路:参考组合,递归,添加数组元素的所有组合到结果集中;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
//将遍历的当前数字加到每一个子集上,生成新的子集
List<List<Integer>> res = new ArrayList<>();
//需要先添加一个空链表子集
res.add(new ArrayList<>());
sub2(0,nums,res,new ArrayList<>());
return res;
}
//递归回溯,
private void sub2(int start, int[] nums, List<List<Integer>> res, List<Integer> sub) {
for (int i = start; i < nums.length; i ++) {//遍历添加
sub.add(nums[i]);//添加当前数字到子集
res.add(new ArrayList<>(sub));//添加子集到结果集合
//递归
sub2(i + 1, nums, res, sub);
//回溯
sub.remove(sub.size() - 1);
}
}
}