给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
//set去重
class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
int size=nums.size();
int scale=size;
size--;
set<vector<int>> ret;
vector<int>tmp;
vector<int>copy;
for(int i=0;i<scale;i++)
{
tmp.push_back(i);
}
while(scale>0)
{
for(int i=0;i<scale;i++)
{
copy.push_back(nums[tmp[i]]);
}
ret.insert(copy);
copy.clear();
int pos=scale-1;
while(pos>=0)
{
if(tmp[pos]<(size-(scale-1-pos)))
{
break;
}
pos--;
}
if(pos<0)
{
scale--;
for(int i=0;i<scale;i++)
{//重置 容器内数字
tmp[i]=i;
}
continue;
}
tmp[pos]++;
for(int i=pos+1;i<scale;i++)
{
tmp[i]=tmp[i-1]+1;
}
}
ret.insert(copy);
return vector<vector<int>>(ret.begin(),ret.end());
}
};
//手动去重
class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>> ret;
vector<int> tmp;
ret.push_back(tmp);
//保存起始位置
vector<int> begin_pos;
//第一位保存插入元素在begin_pos 中的位置,第二个数保存插入元素在nums 中的位置
vector<vector<int>> info;
info.push_back(tmp);
for(int i=0;i<nums.size();i++)
{
if(i>0&&nums[i]==nums[i-1])continue;
//长度为1的子集插入
tmp.push_back(begin_pos.size());
tmp.push_back(i);
info.push_back(tmp);
tmp.clear();
//记录元素位置
begin_pos.push_back(i);
//插入当前结果至返回数组中
tmp.push_back(nums[i]);
ret.push_back(tmp);
tmp.clear();
}
//将末尾位置插入
begin_pos.push_back(nums.size());
int start=1,end=ret.size();
for(int i=2;i<=nums.size();++i)
{
for(int j=start;j<end;j++)
{
vector<int> tmp_info=info[j];
tmp=ret[j];
//判断是否有重复数字
if(tmp_info[1]+1<begin_pos[tmp_info[0]+1])
{
tmp_info[1]++;
tmp.push_back(nums[tmp_info[1]]);
ret.push_back(tmp);
info.push_back(tmp_info);
tmp.clear();
}
//追加不重复数字
for(int k=tmp_info[0]+1;k<begin_pos.size()-1;k++)
{
tmp_info[0]=k;
tmp_info[1]=begin_pos[k];
info.push_back(tmp_info);
tmp=ret[j];
tmp.push_back(nums[tmp_info[1]]);
ret.push_back(tmp);
tmp.clear();
}
}
start=end;
end=ret.size();
}
return ret;
}
};
//set去重
执行用时 : 20 ms, 在Subsets II的C++提交中击败了64.05% 的用户
内存消耗 : 9.6 MB, 在Subsets II的C++提交中击败了43.67% 的用户
//手动去重
执行用时 : 16 ms, 在Subsets II的C++提交中击败了92.34% 的用户
内存消耗 : 9.6 MB, 在Subsets II的C++提交中击败了41.19% 的用户