【Leetcode每日一题】 穷举vs暴搜vs深搜vs回溯vs剪枝_全排列 - 子集(解法2)(难度⭐⭐)(72)

1. 题目解析

题目链接:78. 子集

这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。

2.算法原理

为了生成一个给定数组 nums 的所有子集,我们可以利用一种称为回溯(backtracking)的算法策略。回溯法通过递归的方式,在每一步选择是否将当前元素包含在子集中,并继续处理后续的元素。由于每个元素都可以被选择或不选择,因此总共会产生 2^n 个子集(其中 n 是数组 nums 的长度)。

算法步骤:
  1. 定义递归函数
    • 函数名:dfs(深度优先搜索)
    • 参数:
      • res:存储所有子集的二维向量
      • ans:当前正在构建的子集
      • nums:输入数组
      • step:当前处理的元素下标
    • 返回值:无(函数通过修改参数 res 来返回结果)
  2. 递归结束条件
    • step 等于 nums 的长度时,表示已经处理了数组中的所有元素,此时将 ans 加入到 res 中,并返回。
  3. 递归过程
    • 在每一步,都有两种选择:
      • 不选择当前元素 :保持 ans 不变,递归调用 dfs 函数处理下一个元素(step + 1)。
      • 选择当前元素 :将 nums[step] 添加到 ans 的末尾,然后递归调用 dfs 函数处理下一个元素。在递归返回后,需要从 ans 中移除最后添加的元素(回溯),以确保下一次递归调用时 ans 的状态是正确的。
  4. 结果返回
    • 递归结束后,res 将包含 nums 的所有子集。

3.代码编写

cpp 复制代码
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++) {
            path.push_back(nums[i]);
            dfs(nums, i + 1);
            path.pop_back(); // 恢复现场
        }
    }
};

The Last

嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。

觉得有点收获的话,不妨给我点个吧!

如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~

相关推荐
唐叔在学习几秒前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA20 分钟前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
tianmu_sama20 分钟前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
chengooooooo21 分钟前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc28 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
羚羊角uou35 分钟前
【C++】优先级队列以及仿函数
开发语言·c++
姚先生9739 分钟前
LeetCode 54. 螺旋矩阵 (C++实现)
c++·leetcode·矩阵
FeboReigns41 分钟前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns44 分钟前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++
264玫瑰资源库1 小时前
从零开始C++棋牌游戏开发之第二篇:初识 C++ 游戏开发的基本架构
开发语言·c++·架构