一、题目描述
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
二、题解
(1)回溯
整体思路:
- 遇到
nums的一个元素(包括空集[ ])就把该元素添加进集合tmp,直到tmp的size达到nums数组的大小,然后回溯,怎么回溯? - 在本次循环中,先去掉
tmp后面的一个元素,因为一次循环中,j 是不会减小,只会增加,所以,每次去掉tmp的最后一个元素,那么就会回溯一层,而每回溯一层,就会去掉tmp的最后一个元素 - 直到回到
j==0处,j然后自增,把nums[j](即nums[1])add进集合tmp,
public class Main {
public static List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> subsets = new LinkedList<>();
backtrack(0,nums, subsets, new ArrayList<Integer>());
return subsets;
}
private static void backtrack(int i, int[] nums, List<List<Integer>> ans, ArrayList<Integer> tmp) {
ans.add(new ArrayList<Integer>(tmp));
for (int j = i; j < nums.length; j++) {
tmp.add(nums[j]);
backtrack(j+1, nums, ans, tmp);
tmp.remove(tmp.size()-1);
}
}
public static void main(String[] args) {
int[] nums = {1,2,3};
System.out.println(subsets(nums));
}
}
复杂度分析
- 时间复杂度:
- tmp集合用 ArrayList 只要 1 ms 击败99.31%
- 用 LinkedList 要 2 ms击败35.92%
- 时间差别主要在
tmp.remove(tmp.size()-1);这里,在数据量不大的情况下,LinkedList 在查找方面用到的时间比较多。
- 空间复杂度: