题目:
给定一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集不能包含重复的子集。你可以按 任意顺序 返回解集。
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
输入:nums = [0]
输出:[[],[0]]
分析:
具体操作详见注释
如果输入的集合有n个元素,由于每个元素都有2个选项,因此总的时间复杂度是O(2^n)。
代码:
import java.util.LinkedList;
import java.util.List;
public class Subsets {
public static void main(String[] args) {
Subsets subsets = new Subsets();
int[] nums = {1,2,3};
List<List<Integer>> subsets1 = subsets.subsets(nums);
System.out.println(subsets1);
}
public List<List<Integer>> subsets(int[] nums){
List<List<Integer>> result = new LinkedList<>();
if (nums.length == 0){
return result;
}
// 第一个参数是数组nums,包含输入集合的所有数字,可以逐一从集合中取出一个数字并选择是否将该数字添加到子集中。
// 第二个参数是当前取出的数字在数组nums中的下标,也代表递归层数。
// 第三个参数是当前子集。
// 第四个参数result是所有已经生成的子集。
helper(nums,0,new LinkedList<Integer>(),result);
return result;
}
private void helper(int[] nums, int index, LinkedList<Integer> subset, List<List<Integer>> result) {
if (index == nums.length){
// result添加的是subset的一个拷贝,而不是subset本身
// 因为之后还需要修改subset以便得到其他的子集,同时避免已经添加到result中的子集被修改,在result中添加subset的拷贝可以避免不必要的修改
result.add(new LinkedList<>(subset));
}else if (index < nums.length){
helper(nums,index+1,subset,result);
subset.add(nums[index]);
helper(nums,index+1,subset,result);
// 在回溯到父节点,以便尝试父节点的其他选项,在回溯父节点之前,应该清除已经对子集状态进行的修改
subset.removeLast();
}
}
}