LeetCode:90 子集 II 动态规划思想

题目描述

给定一个可能包含重复元素的整数数组 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;
    }
};
发布了171 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/104526065