文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C++实现LeetCode(90.子集合之二)

2024-04-02 19:55

关注

[LeetCode] 90. Subsets II 子集合之二

Given a collection of integers that might contain duplicates, S, return all possible subsets.

Note:

For example,
If S = [1,2,2], a solution is:

[
[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到当前子集的个数,若相同,则新子集个数减去之前循环时子集的个数当做起点来循环,这样就不会产生重复了,代码如下:

解法一:


class Solution {
public:
    vector<vector<int>> subsetsWithDup(vector<int> &S) {
        if (S.empty()) return {};
        vector<vector<int>> res(1);
        sort(S.begin(), S.end());
        int size = 1, last = S[0];
        for (int i = 0; i < S.size(); ++i) {
            if (last != S[i]) {
                last = S[i];
                size = res.size();
            }
            int newSize = res.size();
            for (int j = newSize - size; j < newSize; ++j) {
                res.push_back(res[j]);
                res.back().push_back(S[i]);
            }
        }
        return res;
    }
};

整个添加的顺序为:

[]
[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的叶节点,因为它们是重复的子集,应被抛弃。代码如下:

解法二:


class Solution {
public:
    vector<vector<int>> subsetsWithDup(vector<int> &S) {
        if (S.empty()) return {};
        vector<vector<int>> res;
        vector<int> out;
        sort(S.begin(), S.end());
        getSubsets(S, 0, out, res);
        return res;
    }
    void getSubsets(vector<int> &S, int pos, vector<int> &out, vector<vector<int>> &res) {
        res.push_back(out);
        for (int i = pos; i < S.size(); ++i) {
            out.push_back(S[i]);
            getSubsets(S, i + 1, out, res);
            out.pop_back();
            while (i + 1 < S.size() && S[i] == S[i + 1]) ++i;
        }
    }
};

整个添加的顺序为:

[]
[1]
[1 2]
[1 2 2]
[2]
[2 2]

到此这篇关于C++实现LeetCode(90.子集合之二)的文章就介绍到这了,更多相关C++实现子集合之二内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯