给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
这题很自然的会想到按照位运算来解题,比如一个数组,含有[1,2,3],也就是长度为3时,一共每一位都有两种可能,有或者没有,那三位的话一共有2^3=8种可能,所有的情况为{000,001,010,011,100,101,110,111},按照这个结果就可以获取到所有不相同的子串了。
思路很简单,但是用到的运算符我也是第一次用,真是惭愧,写这题主要花的时间都是用在理解运算符上了。
首先:
int n = nums.size();
int all = 1 << n;
第二句的意思就是对1左移n位,其实得到的结果就是1*2^n=2^n,也就是得出一共有2^n个子集,接下来就是挨个求这些子集了。
还有一个:
(i & (1 << j)) != 0,这句是关键语句,平时我们使用的一般是&&,表示与操作,但是一个&表示的是按照位进行与运算,比如
7&63=7,因为把7和63分别转化成二进制数为000111和111111,按照位相与的话得到的结果就是000111=7,而1<<j的意思则是将1往左移动j位,j从0到n-1,若该数组为[1,2,3],则1<<j分别为001,010,100,再分别和i按位相与,就能得到第i个子集中,哪些位是0,哪些位是1,把为1的对应元素加入到那个子集中。
代码如下:
vector<vector<int>> subsets(vector<int>& nums) {
int n = nums.size();
int all = 1 << n; //得出共有多少个子集
vector<vector<int>> res;
for(int i = 0; i < all; i++){
vector<int> vec;
for(int j = 0; j < nums.size(); j++)
{
if((i & (1 << j)) != 0) //&表示按位与操作
{
vec.push_back(nums[j]);
}
}
res.push_back(vec);
}
return res;
}
参考博文:https://blog.csdn.net/py13060203/article/details/86763686