官方题解https://leetcode-cn.com/problems/subsets/solution/zi-ji-by-leetcode-solution/
不是很懂【每种状态需要O(n)时间构造子集】。
子集枚举 - 递归法(回溯法) :
cur=0,1,2的时候都会递归两次,就是含nums[cur]往后递归一次,不含nums[cur]往后递归一次,所以一共有2^n个结果。
递归时深度最多为n。
class Solution {
public:
vector<vector<int>> re;
vector<int> path;
vector<vector<int>> subsets(vector<int>& nums) {
int len=nums.size();
int i;
dfs(nums,0,len);
return re;
}
void dfs(vector<int>& nums,int cur,int len){
if(cur==len){
re.push_back(path);
return;
}
path.push_back(nums[cur]); //push之后递归,会得到含nums[cur]的子集
dfs(nums,cur+1,len);
path.pop_back();
dfs(nums,cur+1,len); //pop之后继续递归,会得到不含nums[cur]的子集
}
};
子集枚举 - 迭代法【用二进制掩码表示子集】
class Solution {
public:
vector<int> subset;
vector<vector<int>> re;
vector<vector<int>> subsets(vector<int>& nums) {
int n = nums.size();
for(int mask=0;mask<(1<<n);++mask){ //1<<n:1左移n位,即2^n
subset.clear(); //别忘了新子集开始前要清空
for(int i=0;i<n;++i)
if(mask&(1<<i)) //1左移i位,如果mask的第i位有效,就会将nums[i]加入subset
subset.push_back(nums[i]);
re.push_back(subset);
}
return re;
}
};