Leetcode刷题详解——子集

1. 题目链接:78. 子集

2. 题目描述:

给你一个整数数组 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 中的所有元素 互不相同

3. 解法1:

3.1 算法思路:

为了获取nums数组的所有子集,我们需要对数组的每个元素进行选择或不选择的操作,即nums数组一定存在2^(数组长度)个子集。对于查找子集,具可以定义一个数组,来记录当时的状态,并对其进行递归。

3.2 递归流程:

  1. 递归结束条件:如果当前需要处理的元素下标越界,则记录当前状态并直接返回
  2. 在递归过程中,对于每个元素,我们有两种选择:
    1. 不选择当前元素,直接递归到下一个元素
    2. 选择当前元素,将其添加到数组末尾后递归到下一个元素,然后在递归结束时撤回添加操作
  3. 所有符合条件的状态都将被记录下来,返回即可

3.3 C++算法代码:

c++ 复制代码
class Solution {
    vector<vector<int>> ret; // 存储所有子集的结果
    vector<int> path; // 当前路径(即当前子集)
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(nums,0); // 从第一个元素开始进行深度优先搜索
        return ret; // 返回所有子集的结果
    }
    void dfs(vector<int>&nums,int pos)
    {
        if(pos==nums.size()) // 如果已经遍历完所有元素
        {
            ret.push_back(path); // 将当前路径(即当前子集)添加到结果中
            return; // 结束当前递归
        }
        // 选
        path.push_back(nums[pos]); // 将当前元素添加到当前路径中
        dfs(nums,pos+1); // 继续向下一层递归,处理下一个元素
        path.pop_back(); // 恢复现场,即移除当前路径中的最后一个元素
        // 不选
        dfs(nums,pos+1); // 继续向下一层递归,处理下一个元素,但不将当前元素添加到当前路径中
    }
};

4. 解法2:

4.1 算法思路:

对于每个元素有两种选择:

  1. 不进行任何操作;

  2. 将其添加至当前状态的集合。

    在递归时我们需要保证递归结束时当前的状态与进行递归操作前的状态不变,而当我们在选择进行步骤2进行递归时,当前状态会发生变化,因此我们需要在递归结束时撤回添加操作,即进行回溯

4.2 C++算法代码:

c++ 复制代码
class Solution {
    vector<vector<int>> ret; // 存储所有子集的结果
    vector<int> path; // 当前路径(即当前子集)
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(nums,0); // 从第一个元素开始进行深度优先搜索
        return ret; // 返回所有子集的结果
    }
    void dfs(vector<int>&nums,int pos)
    {
        ret.push_back(path); // 将当前路径添加到结果中
        for(int i=pos;i<nums.size();i++) // 遍历从pos开始的剩余元素
        {
            path.push_back(nums[i]); // 将当前元素添加到当前路径中
            dfs(nums,i+1); // 继续向下一层递归,处理下一个元素
            path.pop_back(); // 恢复现场,即移除当前路径中的最后一个元素
        }
    }
};
相关推荐
水木流年追梦1 分钟前
CodeTop Top 300 热门题目8-字符串解码
linux·运维·服务器·前端·算法·leetcode
lcj25112 分钟前
精选5大高频链表与数组算法详解:从旋转数组到链表公共节点,LeetCode实战代码+图解全解析
算法·leetcode·链表
xin_nai3 分钟前
LeetCode热题100(Java)(4)子串
java·算法·leetcode
一只数据集8 分钟前
机器学习多领域综合数据集分析-包含基因表达时间序列分类回归数据-适用于算法训练模型评估科研应用
人工智能·算法·数据分析
c++之路16 分钟前
C++ 命名空间(Namespace)
开发语言·c++·算法
jiang_bluetooth1 小时前
奈奎斯特第一准则理解和WIFI OFDM的关联
算法
DuHz8 小时前
论文精读:大语言模型 (Large Language Models, LLM) —— 一项调查
论文阅读·人工智能·深度学习·算法·机器学习·计算机视觉·语言模型
加农炮手Jinx9 小时前
LeetCode 72. Edit Distance 题解
算法·leetcode·力扣
借雨醉东风9 小时前
程序分享--常见算法/编程面试题:旋转矩阵
c++·线性代数·算法·面试·职场和发展·矩阵
_深海凉_9 小时前
LeetCode热题100-打家劫舍
算法·leetcode·职场和发展