常用的网站开发,网站优化检测,鲜花店网站页面-欧美模板1psd,成立公司合作协议书范本Medium#xff01; 题目描述#xff1a; 给定一个可能包含重复元素的整数数组 nums#xff0c;返回该数组所有可能的子集#xff08;幂集#xff09;。 说明#xff1a;解集不能包含重复的子集。 示例: 输入: [1,2,2]
输出:
[[2],[1],[1,2,2],[2,2],[1,2],[]
] 解题思路 题目描述 给定一个可能包含重复元素的整数数组 nums返回该数组所有可能的子集幂集。 说明解集不能包含重复的子集。 示例: 输入: [1,2,2]
输出:
[[2],[1],[1,2,2],[2,2],[1,2],[]
] 解题思路 这道子集合之二是之前那道 Subsets 子集合 的延伸这次输入数组允许有重复项其他条件都不变只需要在之前那道题解法的基础上稍加改动便可以做出来我们先来看非递归解法拿题目中的例子[1 2 2]来分析根据之前 Subsets 子集合 里的分析可知当处理到第一个2时此时的子集合为[], [1], [2], [1, 2]而这时再处理第二个2时如果在[]和[1]后直接加2会产生重复所以只能在上一个循环生成的后两个子集合后面加2发现了这一点题目就可以做了我们用last来记录上一个处理的数字然后判定当前的数字和上面的是否相同若不同则循环还是从0到当前子集的个数若相同则新子集个数减去之前循环时子集的个数当做起点来循环这样就不会产生重复了。 C解法一 1 class Solution {2 public:3 vectorvectorint subsetsWithDup(vectorint S) {4 if (S.empty()) return {};5 vectorvectorint res(1);6 sort(S.begin(), S.end());7 int size 1, last S[0];8 for (int i 0; i S.size(); i) {9 if (last ! S[i]) {
10 last S[i];
11 size res.size();
12 }
13 int newSize res.size();
14 for (int j newSize - size; j newSize; j) {
15 res.push_back(res[j]);
16 res.back().push_back(S[i]);
17 }
18 }
19 return res;
20 }
21 }; 整个添加的顺序为 [][1][2][1 2][2 2][1 2 2] 对于递归的解法根据之前 Subsets 子集合 里的构建树的方法在处理到第二个2时由于前面已经处理了一次2这次我们只在添加过2的[2] 和 [1 2]后面添加2其他的都不添加那么这样构成的二叉树如下图所示 [] / \ / \ / \[1] []/ \ / \/ \ / \ [1 2] [1] [2] []/ \ / \ / \ / \[1 2 2] [1 2] X [1] [2 2] [2] X [] 代码只需在原有的基础上增加一句话while (S[i] S[i 1]) i; 这句话的作用是跳过树中为X的叶节点因为它们是重复的子集应被抛弃。 C解法二 1 class Solution {2 public:3 vectorvectorint subsetsWithDup(vectorint S) {4 if (S.empty()) return {};5 vectorvectorint res;6 vectorint out;7 sort(S.begin(), S.end());8 getSubsets(S, 0, out, res);9 return res;
10 }
11 void getSubsets(vectorint S, int pos, vectorint out, vectorvectorint res) {
12 res.push_back(out);
13 for (int i pos; i S.size(); i) {
14 out.push_back(S[i]);
15 getSubsets(S, i 1, out, res);
16 out.pop_back();
17 while (i 1 S.size() S[i] S[i 1]) i;
18 }
19 }
20 }; 整个添加的顺序为 [][1][1 2][1 2 2][2][2 2] 转载于:https://www.cnblogs.com/ariel-dreamland/p/9159492.html