博客
关于我
LeetCode:Subsets I II
阅读量:804 次
发布时间:2023-01-31

本文共 2894 字,大约阅读时间需要 9 分钟。

求集合的所有子集问题

求集合的所有子集,需要考虑集合是否有重复元素以及元素的顺序要求。以下是详细的解决方案和分析。

一、给定问题描述

  • 问题要求

    • 返回集合的所有子集。
    • 子集中的元素必须按非降序排列。
    • 子集不能包含重复项。
  • 例子分析

    • 对于集合 [1,2,3],所有子集包括:[ ], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]
    • 对于集合 [1,2,2],所有子集包括:[ ], [1], [2], [2] (重复), [1,2,2], [2,2], [1,2]
  • 三、解决方案

  • 算法一:DFS方法

  • 代码实现

  • #include 
    #include
    using namespace std;class Solution {private: vector
    > res;public: vector
    > subsets(vector
    &S) { // 先排序 sort(S.begin(), S.end()); res.clear(); vector
    tmpres; dfs(S, 0, tmpres); return res; } void dfs(vector
    &S, int iend, vector
    &tmpres) { if (iend == S.size()) { res.push_back(tmpres); return; } // 计算当前位置及之前的相同元素数量 int firstSame = iend; while (firstSame >= 0 && S[firstSame] == S[iend]) firstSame--; firstSame++; int sameNum = iend - firstSame; // 检查是否需要新增 // 如果前面没有该元素或者本应有该元素但选的数量不足 if (sameNum == 0 || (tmpres.size() >= sameNum && tmpres[tmpres.size() - sameNum] == S[iend])) { // 选择当前元素 tmpres.push_back(S[iend]); dfs(S, iend + 1, tmpres); tmpres.pop_back(); } // 不选择当前元素 dfs(S, iend + 1, tmpres); }};
    1. 算法工作原理

      • 排序:先对集合进行排序,确保子集按非降序生成。
      • DFS递归:递归生成所有可能的子集,每次选择或不选择当前元素。
      • 去重机制:通过计算前面相同元素的数量,确保不重复生成包含相同元素的子集。
    2. 算法二:迭代方法

    3. #include 
      #include
      using namespace std;class Solution {private: vector
      > res;public: vector
      > subsets(vector
      &S) { sort(S.begin(), S.end()); res.clear(); vector
      empty; res.push_back(empty); int last = S.empty() ? 0 : S[0]; int opResNum = 1; for (int i = 0; i < S.size(); ++i) { if (S[i] != last) { last = S[i]; opResNum = res.size(); } int resSize = res.size(); int opRes = resSize - opResNum; for (int j = opRes; j < resSize; ++j) { res.push_back(res[j]); res.back().push_back(S[i]); } } return res; }};
      1. 算法三:二进制方法(适用于无重复元素)
      2. #include 
        #include
        using namespace std;class Solution {private: vector
        > res;public: vector
        > subsets(vector
        &S) { sort(S.begin(), S.end()); if (S.empty()) { return { {} }; } res.clear(); res.push_back({}); unsigned long long bit = 1; int len = S.size(); vector
        tmp; while (bit <= (1LL << len) - 1) { tmp.clear(); unsigned long long cur = bit; for (int i = 0; i < len; ++i) { if (cur & 1) { tmp.push_back(S[i]); } cur >>= 1; } res.push_back(tmp); bit++; } return res; }};
        1. 总结
          • 选择合适的算法:

            • 如果集合中没有重复元素,可以使用二进制方法或迭代方法。
            • 如果集合中存在重复元素,建议使用基于DFS的算法,确保生成唯一的子集。
          • 注意事项

            • 理解子集生成的顺序和方式,避免重复。
            • 高效处理重复元素的方法,减少不必要的递归深度或循环次数。

          通过以上方法,可以高效地生成集合的所有子集,确保在说明顺序和唯一性要求下,正确性和性能。

    转载地址:http://uqgyk.baihongyu.com/

    你可能感兴趣的文章
    nginx配置全解
    查看>>
    Nginx配置参数中文说明
    查看>>
    Nginx配置后台网关映射路径
    查看>>
    nginx配置域名和ip同时访问、开放多端口
    查看>>
    Nginx配置多个不同端口服务共用80端口
    查看>>
    Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
    查看>>
    Nginx配置如何一键生成
    查看>>
    Nginx配置实例-动静分离实例:搭建静态资源服务器
    查看>>
    Nginx配置实例-反向代理实例:根据访问的路径跳转到不同端口的服务中
    查看>>
    Nginx配置实例-反向代理实现浏览器请求Nginx跳转到服务器某页面
    查看>>
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    Nginx配置文件nginx.conf中文详解(总结)
    查看>>
    Nginx配置自带的stub状态实现活动监控指标
    查看>>
    nginx配置详解、端口重定向和504
    查看>>
    Nginx配置负载均衡到后台网关集群
    查看>>
    Nginx配置限流,技能拉满!
    查看>>
    Nginx配置静态代理/静态资源映射时root与alias的区别,带前缀映射用alias
    查看>>
    Nginx面试三连问:Nginx如何工作?负载均衡策略有哪些?如何限流?
    查看>>
    Nginx:NginxConfig可视化配置工具安装
    查看>>
    ngModelController
    查看>>