子集和
子序列
长度为
n
n
n的集合,子集个数是
2
n
2^n
2n个,真子集个数是
2
n
−
1
2^n-1
2n−1个
深搜DFS
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
int n;
vector<vector<int>> subsets(vector<int>& nums) {
n = nums.size();
dfs(nums, 0);
return res;
}
void dfs(vector<int>& nums, int u){
if(u == n) {
res.push_back(path);
return;
}
dfs(nums, u + 1);
path.push_back(nums[u]);
dfs(nums, u + 1);
path.pop_back();
}
};
迭代
123
用三位数的二进制表示选取该集合的子集
000 {}
001 {1}
010 {2}
011 {2,1}
100 {3}
101 {3,1}
110 {3,2}
111 {3,2,1}
只要该数的二进制对应位上是1,就把下标相应的元素放在上面
class Solution {
public:
vector<vector<int>> res;
int n;
vector<vector<int>> subsets(vector<int>& nums) {
n = nums.size();
for(int i = 0; i < 1 << n; i++) { //2^n
vector<int> now;
for(int j = 0; j < n; j++ ){
if(i >> j & 1) now.push_back(nums[j]);
}
res.push_back(now);
}
return res;
}
};
事实证明,迭代的效率更高。
又写了一遍
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
for(int i = 0; i < 1 << nums.size(); i++){ //用二进制每一位的状态来表示该数选与不选
vector<int> temp;
for(int j = 0; j < nums.size(); j++){ //如果当前位是0则不选选 为1则选
if(i>>j&1) temp.push_back(nums[j]);
}
res.push_back(temp);
}
return res;
}
};