题目描述
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
**说明:**解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
方法一
已知子集一定有空集
每增加一个元素则子集个数翻倍,其加倍的就是在原有的子集后面添加该元素形成的新的子集
例如 {a, b, c}的子集必有空集 {}
遍历到a时形成 {}, {a}
遍历到b时形成 {}, {a}, {b}, {a, b},其就是在上一行的子集中后面添加了b形成了新的子集
遍历到c时形成 {}, {a}, {b}, {a, b}, {c}, {a, c}, {b, c}, {a, b, c},同理也是在已有的子集后面添加了c形成新的子集
实现代码
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
ans.add(new ArrayList<>()); //添加空集
for (int v:nums) {
int lenght = ans.size();
for(int i = 0;i<lenght; i++){
List<Integer> tmp = new ArrayList<Integer>(ans.get(i)); //获取已有的子集
tmp.add(v); //已有的子集后添加新的元素,形成新子集
ans.add(tmp); //增加子集
}
}
return ans;
}
}
方法二
子集中对于每一个元素有存在和不存在两种状态,所以子集的个数有2^n个
如果以1表示该元素在子集中,0表示该元素不在子集中,其n个元素的子集对应的所有情况可以用1~2^n的数的二进制表示
例如 {a, b, c}的子集情况有
| 二进制情况 | 对应子集情况 |
|---|---|
| 000 | {} |
| 001 | {c} |
| 010 | {b} |
| 011 | {b, c} |
| 100 | {a} |
| 101 | {a, c} |
| 110 | {a, b} |
| 111 | {a, b, c} |
实现代码
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
int numsSize = nums.size();
int setSize = pow(2,numsSize);
vector<vector<int>> ans;
for(unsigned int i=0;i<setSize;i++){
vector<int>tmp;
for(unsigned int j=0;j<numsSize;j++){
unsigned int flag = (unsigned int)1<<j;
if(flag&i){
tmp.push_back(nums[j]);
}
}
ans.push_back(tmp);
}
return ans;
}
};
293

被折叠的 条评论
为什么被折叠?



