给你一个整数数组
nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
- 1
- 2
示例 2:
输入:nums = [0] 输出:[[],[0]]
- 1
- 2
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums
中的所有元素 互不相同
为了获取nums
数组的所有子集,我们需要对数组的每个元素进行选择或不选择的操作,即nums
数组一定存在2^(数组长度)个子集。对于查找子集,具可以定义一个数组,来记录当时的状态,并对其进行递归。
class Solution {
vector> ret; // 存储所有子集的结果
vector path; // 当前路径(即当前子集)
public:
vector> subsets(vector& nums) {
dfs(nums,0); // 从第一个元素开始进行深度优先搜索
return ret; // 返回所有子集的结果
}
void dfs(vector&nums,int pos)
{
if(pos==nums.size()) // 如果已经遍历完所有元素
{
ret.push_back(path); // 将当前路径(即当前子集)添加到结果中
return; // 结束当前递归
}
// 选
path.push_back(nums[pos]); // 将当前元素添加到当前路径中
dfs(nums,pos+1); // 继续向下一层递归,处理下一个元素
path.pop_back(); // 恢复现场,即移除当前路径中的最后一个元素
// 不选
dfs(nums,pos+1); // 继续向下一层递归,处理下一个元素,但不将当前元素添加到当前路径中
}
};
对于每个元素有两种选择:
不进行任何操作;
将其添加至当前状态的集合。
在递归时我们需要保证递归结束时当前的状态与进行递归操作前的状态不变,而当我们在选择进行步骤2进行递归时,当前状态会发生变化,因此我们需要在递归结束时撤回添加操作,即进行回溯
class Solution {
vector> ret; // 存储所有子集的结果
vector path; // 当前路径(即当前子集)
public:
vector> subsets(vector& nums) {
dfs(nums,0); // 从第一个元素开始进行深度优先搜索
return ret; // 返回所有子集的结果
}
void dfs(vector&nums,int pos)
{
ret.push_back(path); // 将当前路径添加到结果中
for(int i=pos;i