全子集问题(subset)
全子集问题的三种解法:
1.回溯法
回溯是经典的解法,有固定的模板,用递归实现。
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> subs;
vector<int> sub;
genSubsets(nums, 0, sub, subs);
return subs;
}
void genSubsets(vector<int>& nums, int start, vector<int>& sub, vector<vector<int>>& subs) {
subs.push_back(sub);
for (int i = start; i < nums.size(); i++) {
sub.push_back(nums[i]);
genSubsets(nums, i + 1, sub, subs);
sub.pop_back();
}
}
};
2.迭代法
初始为空集[ ]
将上一次的解复制一遍,并往里加元素[ ][ ]→[][1]
将上一次的解复制一遍,并往里加元素[ ][1][ ][1]→[ ][1][2][1,2]
重复复制步骤[ ][1][2][1,2][ ][1][2][1,2]→[ ][1][2][1,2][3][1,3][2,3][1,2,3]
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> subs(1, vector<int>());
for (int i = 0; i < nums.size(); i++) {
int n = subs.size();
for (int j = 0; j < n; j++) {
subs.push_back(subs[j]);
subs.back().push_back(nums[i]);
}
}
return subs;
}
};
3.bit映射法
000~111共8种排列,对应着8种子集,每一bit对应着一个元素
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
sort(nums.begin(), nums.end());
int num_subset = pow(2, nums.size());
vector<vector<int> > res(num_subset, vector<int>());
for (int i = 0; i < nums.size(); i++)
for (int j = 0; j < num_subset; j++)
if ((j >> i) & 1)
res[j].push_back(nums[i]);
return res;
}
};
【Reference】
https://leetcode.com/discuss/46668/recursive-iterative-manipulation-solutions-explanations