给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3],
[2,3], [1,2], [] ]
参考算法:
(按位与操作)
https://blog.youkuaiyun.com/qq_32805671/article/details/82180036
第一次使用位运算的方法解题,对于本题,采用位运算的方法真的很方便。若nums的长度为n,则遍历2n2n次,每次得到一个子集:
将i看成二进制码流,判断j位是0还是1,如果为1,则选中nums[j]添加到子集中,从而得到一个子集vec
将子集vec保存进res
返回res
class Solution { public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
if(nums.empty())
return res;
res.push_back({});
int n = nums.size();
for(int i = 0; i < n; i++)
{
int nRes = res.size();
for(int j = 0; j < nRes; j++)
{
vector<int> temp = res[j];
temp.push_back(nums[i]);
res.push_back(temp);
}
}
return res;
} };
其中,不理解之处为:all = 1<<n
朋友解释说是1向左移n位,得到结果为2的n次方,即子集个数;
所以i即为结果中的第i个元素,
尝试了一下输出i,j 和nums[j],结果如下:
i = 0 , j = 0
i = 0 , j = 1
i = 0 , j = 2
i = 1 , j = 0
1
i = 1 , j = 1
i = 1 , j = 2
i = 2 , j = 0
i = 2 , j = 1
2
i = 2 , j = 2
i = 3 , j = 0
1
i = 3 , j = 1
2
i = 3 , j = 2
i = 4 , j = 0
i = 4 , j = 1
i = 4 , j = 2
3
等等~
1<<j ,分别等于0001(j=0), 0010(j=1), 0100(j=2)
i&j!=0,即表示第i个元素中包含nums[j];
即i=0时,vec= {};
i = 1时, vec= {1};
i = 2时, vec= {2};
i = 3时, vec= {1,2};
以此类推。
刚开始不理解这种思路,不过仿照这个输出,有了自己的思路:
若nums = { }, 则res = { };
若nums = {1},则res= {{},{1}};
同理,若nums中每新增一个元素,即res中元素个数为原来二倍,新增子集为原来基础上每个子集中增加新增的元素。
代码如下:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
if(nums.empty())
return res;
res.push_back({});
int n = nums.size();
for(int i = 0; i < n; i++)
{
int nRes = res.size();
for(int j = 0; j < nRes; j++)
{
vector<int> temp = res[j];
temp.push_back(nums[i]);
res.push_back(temp);
}
}
return res;
}
};