思路:首先想到对于每个元素,选或者不选。
法一:位运算
可以发现 0/1 序列对应的二进制数正好从 0 到 2^n−1。我们可以枚举 mask∈[0,2^n−1],mask 的二进制表示是一个 0/1 序列,我们可以按照这个 0/1 序列在原集合当中取数。当我们枚举完所有 2 ^n个 mask,我们也就能构造出所有的子集。
我只能说位运算的代码,一看一个妙哉。
class Solution {
vector<int> set;
vector<vector<int>> ans;
public:
vector<vector<int>> subsets(vector<int>& nums) {
int n=nums.size();
for(int i=0;i<(1<<n);i++)
{
set.clear();
for(int j=0;j<n;j++)
{
if(i&(1<<j))
{
set.push_back(nums[j]);
}
}
ans.push_back(set);
}
return ans;
}
};
法二:回溯法
class Solution {
vector<int> set;
vector<vector<int>> ans;
void dfs(int u,vector<int>& nums)
{
if(u==nums.size())
{
ans.push_back(set);
return;
}
set.push_back(nums[u]);
dfs(u+1,nums);
set.pop_back();
dfs(u+1,nums);
}
public:
vector<vector<int>> subsets(vector<int>& nums) {
dfs(0,nums);
return ans;
}
};