LeetCode 算法:子集 c++

原题链接🔗子集
难度:中等⭐️⭐️

题目

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:
输入:nums = [0]
输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

子集(幂集)

子集和幂集是集合论中的两个基本概念。

  1. 子集(Subset)

    • 子集是指一个集合的所有元素都属于另一个集合。
    • 如果集合A的所有元素都是集合B的元素,那么我们就说A是B的子集,记作 A ⊆ B 。
    • 空集(不包含任何元素的集合)是所有集合的子集。
  2. 幂集(Power Set)

    • 幂集是指一个集合所有可能子集的集合,包括空集和集合本身。
    • 如果集合A的元素个数是n,那么A的幂集将包含 2n 个子集。
    • 幂集的元素是原集合的子集,因此幂集的元素数量总是2的幂。

例如,如果有一个集合 A = {1, 2} ,那么:

  • 它的子集包括:∅(空集),{1} ,{2},{1, 2}。
  • 它的幂集就是:{∅, {1}, {2}, {1, 2} }。

幂集的大小是原集合大小的2倍,因为每个元素都有“在”或“不在”两种可能性。

题解

  1. 解题思路

LeetCode上的“子集”问题是一个经典的算法问题,通常指的是找出给定集合的所有可能子集。这个问题可以通过递归或迭代的方式来解决。下面是解决这个问题的一种通用思路:

  • 递归方法(回溯法) :递归方法通常使用回溯法来生成所有可能的子集。基本思路如下:

    • 初始化:创建一个结果列表subsets,用来存储所有可能的子集。
    • 递归函数:定义一个递归函数,该函数接收当前子集current_subset和当前遍历到的数字索引index
    • 递归终止条件:如果index等于给定集合的长度,将当前子集current_subset添加到结果列表subsets中。
    • 递归逻辑
      • 不选择当前索引的元素,递归调用index + 1
      • 选择当前索引的元素,将该元素添加到current_subset中,然后递归调用index + 1
  • 迭代方法(位运算) :迭代方法使用位运算来生成所有可能的子集。基本思路如下:

    • 初始化:创建一个结果列表subsets,用来存储所有可能的子集。
    • 循环:从0到2的n次方(n是集合中元素的数量)进行循环,使用二进制表示当前子集的选择状态。
    • 位运算:对于每个数字i(从0到2^n-1),使用位运算(1 << j) & i来检查集合中的第j个元素是否被选中。
    • 构建子集:根据当前的二进制表示,构建当前子集,并将其添加到结果列表subsets中。

这两种方法各有优缺点,递归方法更直观,但可能会受到递归深度限制;迭代方法不受递归深度限制,但可能在理解上稍微复杂一些。根据具体问题和环境选择合适的方法。

  1. c++ demo
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

class Solution {
public:
    vector<int> t;
    vector<vector<int>> ans;

    vector<vector<int>> subsets(vector<int>& nums) {
        int n = nums.size();
        for (int mask = 0; mask < (1 << n); ++mask) {
            t.clear();
            for (int i = 0; i < n; ++i) {
                if (mask & (1 << i)) {
                    t.push_back(nums[i]);
                }
            }
            ans.push_back(t);
        }
        return ans;
    }
};

// 示例使用
int main() {
    Solution solution;
    std::vector<int> nums = { 1, 2 };
    std::vector<std::vector<int>> result = solution.subsets(nums);

    // 打印所有子集
    for (const auto& subset : result) {
        for (int num : subset) {
            std::cout << num << " ";
        }
        std::cout << " ";
    }
    return 0;
}
  • 输出结果:

| 1 | 2 | 1 2 |

  1. 代码仓库地址:subsets

相关推荐

  1. LeetCode 算法子集 c++

    2024-07-15 04:50:04       21 阅读
  2. leetcode 复原ip、子集

    2024-07-15 04:50:04       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 04:50:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 04:50:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 04:50:04       57 阅读
  4. Python语言-面向对象

    2024-07-15 04:50:04       68 阅读

热门阅读

  1. 赫夫曼编码-C语言

    2024-07-15 04:50:04       20 阅读
  2. WEB安全-文件上传漏洞

    2024-07-15 04:50:04       15 阅读
  3. 线段树最大与最小值模板

    2024-07-15 04:50:04       18 阅读
  4. 使用Arthas定位开发常见问题

    2024-07-15 04:50:04       18 阅读
  5. UOS查看系统信息命令行

    2024-07-15 04:50:04       19 阅读
  6. 【学习笔记】Redis学习笔记——第11章 AOF持久化

    2024-07-15 04:50:04       22 阅读
  7. LeetCode 219. 存在重复元素 II

    2024-07-15 04:50:04       23 阅读
  8. 实验05 单元测试

    2024-07-15 04:50:04       22 阅读
  9. Hash表以及put方法源码的分析

    2024-07-15 04:50:04       21 阅读