【每日算法】LeetCode 78 —— 子集(一百七十)

题目内容

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:

输入:nums = [0]
输出:[[],[0]]

提示

1、1 <= nums.length <= 10
2、-10 <= nums[i] <= 10
3、nums 中的所有元素 互不相同

题解

在本题中,可以采用二进制模拟选择的方法进行求解。具体来说,就是取nums长度的二进制数,每个位置上如果为0,则说明对应位置不选,如果为1则说明对应位置需要选择,这样就可以将集合中全部子集枚举出来。

在操作上,难度在于如何枚举这样的二进制,具体的操作如下:

1、使用一层循环,用于枚举n位二进制的全部情况,在使用内层循环,用于逐个判断每层是否是1或者是0。

2、外层循环中,式子i < 1 << n,这样解读:i 小于 1向左移动n位所代表的数,也就是i小于 2^n。左移是做乘2运算,右移是做除2运算。<<或>>运算符的优先级大于<或>的优先级。

3、每次i枚举之后,让i右移j位,j从0开始,然后与1相与就取出每一位对应的值了

4、根据0或1的值,再取nums对应坐标的值即可。

代码

class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
//采用二进制的方式求解。1代表要,0代表不要。
vector<vector<int>> res;
int n = nums.size();
for(int i = 0; i < 1 << n; i++){
vector<int> path;
for(int j = 0; j < n; j++){
if(i >> j & 1)
//把第j位移动到个位并与上一个1
path.push_back(nums[j]);
}
res.push_back(path);
}
return res;
}
};
Author: Frederic Niu
Link: https://www.fredericniu.cn/2021/06/13/【每日算法】LeetCode-78-——-子集(一百七十)/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
我的公众号