78. Subsets和90. Subsets II

news2025/7/19 21:06:36

目录

78.子集

方法一、迭代法实现子集枚举

方法二、递归法实现子集枚举

方法三、根据子集元素个数分情况收集

方法四、直接回溯法

90.子集二

方法一、迭代法实现子集枚举

方法二、递归法实现子集枚举

方法三、根据子集元素个数分情况收集

方法四、直接回溯法


78.子集

78. Subsets

方法一、迭代法实现子集枚举

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> aset;
        int n = nums.size();
        int m = 1<<n;//pow(2,n);//子集总数是2的n次方个
        for(int mask = 0;mask <m;mask++){
            aset.clear();
            for(int i = 0;i < n;i++){
                if(mask & (1<<i))
                    aset.push_back(nums[i]);
            }
            res.push_back(aset);
        }
        return res;
    }
};

方法二、递归法实现子集枚举

class Solution {
    vector<vector<int>> res;
    vector<int> aset;
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(nums,0);
        return res;
    }

    void dfs(vector<int>& nums,int index){
        if(index == nums.size()){
            res.push_back(aset);
            return;
        }
        //当前子集选择nums[index]
        aset.push_back(nums[index]);
        dfs(nums,index+1);
        aset.pop_back();

        //当前子集不选nums[index]
        dfs(nums,index+1);
    }
};

方法三、根据子集元素个数分情况收集

 子集中元素的个数可以是0,1,2...,nums.size()

对于每一种情况,可以用回溯来收集。

class Solution {
    vector<vector<int>> res;
    vector<int> aset;
public:
    vector<vector<int>> subsets(vector<int>& nums) {
       //子集中元素的个数可以是0,1,2...,nums.size()
       for(int count = 0; count <= nums.size();count++){
            backtracking(nums,0,count);
       }
       return res;
    }

    //从nums中收集元素个数为total_count的子集
    void backtracking(vector<int>& nums,int start,int total_count){
        if(aset.size() == total_count){
            res.push_back(aset);
            return;
        }

        for(int i = start;i < nums.size();i++){
            aset.push_back(nums[i]);
            backtracking(nums,i+1,total_count);
            aset.pop_back();
        }
    }
};

方法四、直接回溯法

class Solution {
    vector<vector<int>> res;
    vector<int> aset;
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        backtracking(nums,0);
        return res;
    }

    void backtracking(vector<int>& nums,int start){
        res.push_back(aset);//收集子集要放在前面,不然会遗漏

        // if(start == nums.size()) //终止条件可不写,因为下面的遍历也是这个条件
        //     return;

        for(int i = start ;i < nums.size();i++){
            aset.push_back(nums[i]);
            backtracking(nums,i+1);
            aset.pop_back();
        }
    }
};

90.子集二

90. Subsets II

方法一、迭代法实现子集枚举

class Solution {
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> res;
        vector<int> aset;
        bool flag = true;
        int n = nums.size();
        int m = 1<<n;
        for(int mask = 0;mask < m;mask++){
            aset.clear();
            flag = true;
            for(int i = 0;i < n;i++){
                if(mask & (1<<i)){
                    if(i > 0 && (mask&(1<<(i-1))) == 0 && nums[i]==nums[i-1]){
                        flag = false;
                        break;
                    }
                    aset.push_back(nums[i]);
                }
            }
            if(flag)
                res.push_back(aset);
        }
        return res;
    }
};

方法二、递归法实现子集枚举

class Solution {
    vector<vector<int>> res;
    vector<int> aset;
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        dfs(false,nums,0);
        return res;
    }

    void dfs(bool choseLast,vector<int>& nums,int index){
        if(index == nums.size()){
            res.push_back(aset);
            return;
        }
        dfs(false,nums,index+1);

        if(!choseLast && index > 0 && nums[index] == nums[index-1])
            return;
        aset.push_back(nums[index]);
        dfs(true,nums,index+1);
        aset.pop_back();
    }
};

方法三、根据子集元素个数分情况收集

class Solution {
    vector<vector<int>> res;
    vector<int> aset;
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());//后面树层去重,需要先排序,让相等的元素相邻
        int n = nums.size();
        //子集中元素的个数可能是0,1,2,...n
        for(int count = 0;count <=n;count++){
            backtracking(nums,0,count);
        }
        return res;
    }

    void backtracking(vector<int>& nums,int start,int total_count){
        if(aset.size() == total_count)
        {
            //子集中元素个数已经达到目标个数total_count
            res.push_back(aset);
            return;
        }

        for(int i = start;i < nums.size();i++){
            if(i > start && nums[i] == nums[i-1])//树层去重,
                continue;//可以把这里的循环理解为回溯树横向上不同子集的遍历,相同元素不跳过会导致重复收集之前收集过的答案
            aset.push_back(nums[i]);
            backtracking(nums,i+1,total_count);//这里的递归是对同一个子集的下一个元素的选取,同一个子集中是允许元素重复的。
            aset.pop_back();
        }
    }
};

方法四、直接回溯法

收集回溯树的结点

class Solution {
    vector<vector<int>> res;
    vector<int> aset;
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        backtracking(nums,0);
        return res;
    }

    void backtracking(vector<int>& nums,int start){
        res.push_back(aset);
        for(int i = start;i < nums.size();i++){
            if(i>start && nums[i]==nums[i-1])
                continue;
            aset.push_back(nums[i]);
            backtracking(nums,i+1);
            aset.pop_back();
        }
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2387419.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch整合SpringBoot

ElasticSearch 整合SpringBoot ES官方提供了各种不同语言的客户端。用来操作ES。这些客户端的本质就是组装DSL语句&#xff0c;通过HTTP请求发送给ES。 设计索引库 跟据数据库的表结构进行ES索引库的创建时。如果字段需要进行倒排索引的时候请为它指定分词器。如果该字段不是…

2025上半年软考高级系统架构设计师经验分享

笔者背景 笔者在成都工作近7年&#xff0c; 一直担任研发大头兵&#xff0c;平日工作主要涵盖应用开发&#xff08;Java&#xff09;与数仓开发&#xff0c;对主流数据库、框架等均有涉猎&#xff0c;但谈不上精通。 最近有一些职业上的想法&#xff0c;了解到软考有那么一丁点…

uni-app学习笔记十二-vue3中创建组件

通过组件&#xff0c;可以很方便地实现页面复用&#xff0c;减少重复页面的创建&#xff0c;减少重复代码。一个页面可以引入多个组件。下面介绍在HBuilder X中创建组件的方法&#xff1a; 一.组件的创建 1.选中项目&#xff0c;右键-->新建目录(文件夹)&#xff0c;并将文…

一键启动多个 Chrome 实例并自动清理的 Bash 脚本分享!

目录 一、&#x1f4e6; 脚本功能概览 二、&#x1f4dc; 脚本代码一览 三、&#x1f50d; 脚本功能说明 &#xff08;一&#xff09;✅ 支持批量启动多个 Chrome 实例 &#xff08;二&#xff09;✅ 每个实例使用独立用户数据目录 &#xff08;三&#xff09;✅ 启动后自…

4 月 62100 款 App 被谷歌下架!环比增长 28%

大家好&#xff0c;我是牢鹅&#xff01;上周刚刚结束的 2025 年 Google I/O 开发者大会&#xff0c; Google Play 带来了一系列的更新&#xff0c;主要围绕提升优质 App 的"发现"、"互动"和"收入"三大核心内容。 这或许正是谷歌生态的一个侧影…

mediapipe标注视频姿态关键点(基础版加进阶版)

前言 手语视频流的识别有两种大的分类&#xff0c;一种是直接将视频输入进网络&#xff0c;一种是识别了关键点之后再进入网络。所以这篇文章我就要来讲讲如何用mediapipe对手语视频进行关键点标注。 代码 需要直接使用代码的&#xff0c;我就放这里了。环境自己配置一下吧&…

PCtoLCD2002如何制作6*8字符

如何不把“等比缩放”前的打勾取消&#xff0c;则无法修改为对应英文字符为6*8。 取消之后就可以更改了&#xff01;

SmartPlayer与VLC播放RTMP:深度对比分析延迟、稳定性与功能

随着音视频直播技术的发展&#xff0c;RTMP&#xff08;实时消息传输协议&#xff09;成为了广泛应用于实时直播、在线教育、视频会议等领域的重要协议。为了确保优质的观看体验&#xff0c;RTMP播放器的选择至关重要。大牛直播SDK的SmartPlayer和VLC都是在行业中广受欢迎的播放…

Qt QPaintEvent绘图事件painter使用指南

绘制需在paintEvent函数中实现 用图片形象理解 如果加了刷子再用笔就相当于用笔画过的区域用刷子走 防雷达&#xff1a; 源文件 #include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QPainter> Widget::Widget(QWidget…

伪创新-《软件方法》全流程引领AI-第1章 04

《软件方法》全流程引领AI-第1章 ABCD工作流-01 对PlantUML们的评价-《软件方法》全流程引领AI-第1章 02 AI辅助的建模步骤-《软件方法》全流程引领AI-第1章 03 第1章 ABCD工作流 1.5 警惕和揭秘伪创新 初中数学里要学习全等三角形、相似三角形、SSS、SAS……&#xff0c;到…

【iOS】 锁

iOS 锁 文章目录 iOS 锁前言线程安全锁互斥锁pthread_mutexsynchronized (互斥递归锁)synchronized问题:小结 NSLockNSRecursiveLockNSConditionNSConditionLock 自旋锁OSSpinLock(已弃用)atomicatomic修饰的属性绝对安全吗?os_unfair_lock 读写锁互斥锁和自旋锁的对比 小结使…

uni-app学习笔记十五-vue3页面生命周期(一)

页面生命周期概览 vue3页面生命周期如下图所示&#xff1a; onLoad 此时页面还未显示&#xff0c;没有开始进入的转场动画&#xff0c;页面dom还不存在。 所以这里不能直接操作dom&#xff08;可以修改data&#xff0c;因为vue框架会等待dom准备后再更新界面&#xff09;&am…

《软件工程》第 14 章 - 持续集成

在软件工程的开发流程中&#xff0c;持续集成是保障代码质量与开发效率的关键环节。本章将围绕持续集成的各个方面展开详细讲解&#xff0c;结合 Java 代码示例与可视化图表&#xff0c;帮助读者深入理解并实践相关知识。 14.1 持续集成概述 14.1.1 持续集成的相关概念 持续集…

Orpheus-TTS:AI文本转语音,免费好用的TTS系统

名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。——苏轼《稼说送张琥》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、Orpheus-TTS&#xff1a;重新定义语音合成的标准1. 什么是Orpheus-TTS&#xff…

STM32 Keil工程搭建 (手动搭建)流程 2025年5月27日07:42:09

STM32 Keil工程搭建 (手动搭建)流程 觉得麻烦跳转到最底部看总配置图 1.获取官方标准外设函数库 内部结构如下: 文件夹功能分别为 图标(用不上)库函数(重点) Libraries/ ├── CMSIS/ # ARM Cortex-M Microcontroller Software Interface Standard…

OpenGL Chan视频学习-7 Writing a Shader inOpenGL

bilibili视频链接&#xff1a; 【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p5&vd_source44b77bde056381262ee55e448b9b1973 函数网站&#xff1a; docs.gl 说明&#xff1a; 1.之后就不再整理具体函数了&#xff0c;网站直接翻译会更直观也会…

顶会新方向:卡尔曼滤波+目标检测

卡尔曼虑波&#xff0b;目标检测创新结合&#xff0c;新作准确率突破100%! 一个有前景且好发论文的方向:卡尔曼滤波&#xff0b;目标检测! 这种创新结合&#xff0c;得到学术界的广泛认可&#xff0c;多篇成果陆续登上顶会顶刊。例如无人机竞速系统 Swift&#xff0c;登上nat…

一起学数据结构和算法(二)| 数组(线性结构)

数组&#xff08;Array&#xff09; 数组是最基础的数据结构&#xff0c;在内存中连续存储&#xff0c;支持随机访问。适用于需要频繁按索引访问元素的场景。 简介 数组是一种线性结构&#xff0c;将相同类型的元素存储在连续的内存空间中。每个元素通过其索引值&#xff08;数…

Linux基本指令篇 —— touch指令

touch是Linux和Unix系统中一个非常基础但实用的命令&#xff0c;主要用于操作文件的时间戳和创建空文件。下面我将详细介绍这个命令的用法和功能。 目录 一、基本功能 1. 创建空文件 2. 同时创建多个文件 3. 创建带有空格的文件名&#xff08;需要使用引号&#xff09; 二、…

【后端高阶面经:消息队列篇】23、Kafka延迟消息:实现高并发场景下的延迟任务处理

一、延迟消息的核心价值与Kafka的局限性 在分布式系统中,延迟消息是实现异步延迟任务的核心能力,广泛应用于订单超时取消、库存自动释放、消息重试等场景。 然而,Apache Kafka作为高吞吐的分布式消息队列,原生并不支持延迟消息功能,需通过业务层或中间层逻辑实现。 1.1…