78.子集
给你一个整数数组 nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入: nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入: nums = [0]
输出:[[],[0]]
提示:
- 1 ≤ n u m s . l e n g t h ≤ 10 1 \leq nums.length \leq 10 1≤nums.length≤10
- − 10 ≤ n u m s [ i ] ≤ 10 -10 \leq nums[i] \leq 10 −10≤nums[i]≤10
nums
中的所有元素 互不相同
解法一(回溯)
思路分析:
- 首先确定该问题为子集问题,使用回溯算法进行求解
- 考虑回溯三要素:
- 考虑回溯的返回值和参数,题目不需要函数返回某值,即返回值为
void
,参数则包括集合,以及下一层递归选取元素的起始索引 - 考虑回溯的结束条件,因为需要获取全部的子集,即当选取元素个数符合
path.size() > 0 && path.size() <= nums.length
时,将子集保存到ans
中 - 考虑回溯的遍历过程,即遍历集合,选取元素,然后继续递归选取,结束递归后进行回溯
- 考虑回溯的返回值和参数,题目不需要函数返回某值,即返回值为
实现代码如下:
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
ans.add(new ArrayList<>(path)); // 获取空集
backtracking(0, nums);
return ans;
}
private void backtracking(int startIndex, int[] nums) {
if (!path.isEmpty() && path.size() <= nums.length) {
ans.add(new ArrayList<>(path));
}
for (int i = startIndex; i < nums.length; ++ i) {
path.add(nums[i]);
backtracking(i+1, nums);
path.remove(path.size()-1);
}
}
}
提交结果如下:
解答成功:
执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:41.8 MB,击败了16.97% 的Java用户
复杂度分析:
- 时间复杂度:
O
(
n
×
2
n
)
O(n \times 2^n)
O(n×2n),
n
表示集合长度,每个集合元素有两种状态,则共有 2 n 2^n 2n个状态,而每种状态需要 O ( n ) O(n) O(n)时间构造子集 - 空间复杂度: O ( n ) O(n) O(n)