题目描述
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/subsets-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
上一篇不包含重复元素【LeetCode:78 子集】
思路:
因为给定的数组可能包含重复元素,我们只考虑元素的种类,对每一种元素,考虑加入多少个就好了
状态转移:
求前 i 种(注意这里是种不是个)元素组成的所有子集,问题转化为:
【前 i-1 种元素组成的所有子集】+ 【前 i-1 种元素组成的所有子集,加上1,2,3....n
个第 i 种元素】
对于第i种元素,出现k次,要考虑加入 1,2,3…k 个的情况,共 k 种情况
这里其实就是考虑k
个相同元素组成的不同子集,比如7,出现3次,那么不同的子集就是 7,77,777
使用一个【哈希map】可以快速的存储元素与其出现次数的映射
代码
class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums)
{
vector<vector<int>> ans;
ans.push_back({});
unordered_map<int, int> m;
for(int i=0; i<nums.size(); i++)
m[nums[i]]++;
for(auto it=m.begin(); it!=m.end(); it++)
{
// 对前i-1种元素组成的所有子集,都加上1~k个新元素
int setsize = ans.size();
for(int j=0; j<setsize; j++)
{
for(int k=1; k<=it->second; k++)
{
ans.push_back(ans[j]);
for(int t=0; t<k; t++)
ans[ans.size()-1].push_back(it->first);
}
}
}
return ans;
}
};