题目描述:
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
AC C++ Solution:
方法1:
递归(回溯):
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> subs;
vector<int> sub;
subsets(nums, 0, sub, subs);
return subs;
}
private:
void subsets(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]);
subsets(nums, i + 1, sub, subs);
sub.pop_back();
}
}
};
方法2:
位操作:
为了给出所有可能的子集,我们只需要耗尽所有可能的数字组合。每个数字只有两种可能性:在子集中或不在子集中。这可以用一点来表示。
使用[1, 2, 3]作为一个例子,1在每两个连续的子集出现一次,2每四个连续的子集出现两次,并且3出现四次,每8子集(最初所有的子集是空的):
[], [], [], [], [], [], [], []
[], [1], [], [1], [], [1], [], [1]
[], [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) {
int n = pow(2, nums.size());
vector<vector<int>> subs(n, vector<int>());
for (int i = 0; i < nums.size(); i++) {
for (int j = 0; j < n; j++) {
if ((j >> i) & 1) { //这个位操作判断移位后的奇偶
subs[j].push_back(nums[i]);
}
}
}
return subs;
}
};
本文深入探讨了子集生成算法的两种实现方法:递归(回溯)与位操作。通过实例解析,详细展示了如何利用这两种方法从给定的整数数组中生成所有可能的子集,包括空集。代码示例清晰地演示了算法的具体实现过程。
332

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



