LeetCode
- 题目地址:
问题描述&解题思路:首先先把两道题的题目说一下,78题问的是给你一个nums数组,要求nums数组的所有子集合,其中nums数组都是没有重复的数字,而90题则是nums中可能有重复的数字。
- 对于78题来说,一个n个不同数字的集合,共有 2n 个子集合,那么可以用2进制表示,其中第i位为1表示要nums[i]进该子集合。于是一个循环产生从0 到 2n−1 的数字,每个数字对应一个子集合,那么就产生完成了。
- 而90题由于有重复的数字,显然这种方法是不行的,比如[1,2,2],101和110对应的子集合都是[1,2],剔除重复的我用set来做,这样保证了集合的唯一性。除此之外,由于集合没有顺序,所以如果是[2,1,2]这样的,集合[1,2]和[2,1]是一样的,所以先做一个排序变成[1,2,2],这样,就不会出现[2,1]这种子集合,所有的子集合都是递增的,不会出现同一个子集合的两种排序方式。
代码如下:
- 78:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
int size = nums.size();
vector<vector<int>> finalRes;
for (int i = 0; i < 1 << size; i++) {
vector<int> res;
aVec(nums,res,i);
finalRes.push_back(res);
}
return finalRes;
}
void aVec(vector<int>& nums, vector<int>& res, int i) {
int count = 0;
while(i) {
if (i & 1) {
res.push_back(nums[count]);
}
count++;
i >>= 1;
}
}
};
- 90
class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
int size = nums.size();
sort(nums.begin(),nums.end());
set<vector<int>> finalRes;
for (int i = 0; i < 1 << size; i++) {
vector<int> res;
aVec(nums,res,i);
finalRes.insert(res);
}
return vector<vector<int>>(finalRes.begin(),finalRes.end());
}
void aVec(vector<int>& nums, vector<int>& res, int i) {
int count = 0;
while(i) {
if (i & 1) {
res.push_back(nums[count]);
}
count++;
i >>= 1;
}
}
};