Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
解答:
1.我的想法,对于任意一个输入{1,2,3},则二进制对应有0~7,这8个数的每位对应1,就把对应的数字输出,若为0,则不输出。因此得到的就是集合。
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
int len = nums.size();
int base = 1;
vector<int> vec;
vector<vector<int>> res;
for(int i = len-1; i >= 0; i--){
base *= 2;
}
for(int j = 0; j <= base-1; j++){
vec.clear();
int jr = j;
int k = len-1;
int r = 0;
while(jr > 0){
int yu = jr % 2;
jr = jr / 2;
if(yu == 1)
r = nums[k];
k--;
if(yu > 0)
vec.push_back(r);
}
sort(vec.begin(),vec.end());
res.push_back(vec);
}
sort(res.begin(),res.end());
res.erase(unique(res.begin(),res.end()),res.end());
return res;
}
2.大牛的做法。
先把总集合输入空集合{},然后一个个数字往上加。对于{1,2,3}。先加1,得到{1},总集合里有{{},{1}}。
再对总集合的每个小集合加入数字2,得到{2},{1,2},则总的集合有{{},{1},{2},{1,2}}。数字3也是如此。
对于重复数字,就用count计数。{1,2,2}。先加1,得到{1},总集合里有{{},{1}}。
再对总集合的每个小集合加入数字2,得到{2},由于count=2,则再加入2,得到集合{2,2}。再对{1}加2,{1,2},再加入{2},得到{1,2,2}。
则总的集合有{{},{1},{2},{2,2},{1,2},{1,2,2}}。
vector<vector<int> > subsetsWithDup(vector<int> &S) {
vector<vector<int> > totalset = {{}};
sort(S.begin(),S.end());
for(int i=0; i<S.size();){
int count = 0; // num of elements are the same
while(count + i<S.size() && S[count+i]==S[i]) count++;
int previousN = totalset.size();
for(int k=0; k<previousN; k++){
vector<int> instance = totalset[k];
for(int j=0; j<count; j++){
instance.push_back(S[i]);
totalset.push_back(instance);
}
}
i += count;
}
return totalset;
}
3.迭代做法
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<vector<int>> ret;
ret.push_back(vector<int>());
sort(nums.begin(), nums.end());
vector<vector<int>> sub;
for (int i = 0; i < nums.size(); ++i) {
if (i == 0 || nums[i] != nums[i-1]) sub = ret;
for (auto& j:sub) j.push_back(nums[i]);
ret.insert(ret.end(), sub.begin(), sub.end());
}
return ret;
}
4.回溯方法
class Solution {
public:
std::vector<std::vector<int> > subsetsWithDup(std::vector<int> &nums) {
std::sort(nums.begin(), nums.end());
std::vector<std::vector<int> > res;
std::vector<int> vec;
subsetsWithDup(res, nums, vec, 0);
return res;
}
private:
void subsetsWithDup(std::vector<std::vector<int> > &res, std::vector<int> &nums, std::vector<int> &vec, int begin) {
res.push_back(vec);
for (int i = begin; i != nums.size(); ++i)
if (i == begin || nums[i] != nums[i - 1]) {
vec.push_back(nums[i]);
subsetsWithDup(res, nums, vec, i + 1);
vec.pop_back();
}
}
};