当前位置: 首页 > article >正文

78. Subsets和90. Subsets II

目录

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,...nfor(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_countres.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.lryc.cn/news/2387419.html

相关文章:

  • VSCode 插件 GitLens 破解方法
  • linux 通过命令将 MinIO 桶的权限设置为 Custom(自定义策略)
  • 模型评价指标介绍
  • ElasticSearch整合SpringBoot
  • ArcGIS Pro 3.4 二次开发 - 知识图谱
  • 2025上半年软考高级系统架构设计师经验分享
  • uni-app学习笔记十二-vue3中创建组件
  • React 虚拟dom
  • 互联网大厂Java求职面试:AI与大模型应用集成中的架构难题与解决方案-1
  • 《算法笔记》13.2小节——专题扩展->树状数组(BIT) 问题 D: 数列-训练套题T10T3
  • 一键启动多个 Chrome 实例并自动清理的 Bash 脚本分享!
  • 4 月 62100 款 App 被谷歌下架!环比增长 28%
  • 图像分割全路线学习(结合论文)
  • Go语言之定义结构体(Struct)-《Go语言实战指南》
  • mediapipe标注视频姿态关键点(基础版加进阶版)
  • PCtoLCD2002如何制作6*8字符
  • SmartPlayer与VLC播放RTMP:深度对比分析延迟、稳定性与功能
  • Qt QPaintEvent绘图事件painter使用指南
  • 伪创新-《软件方法》全流程引领AI-第1章 04
  • win11如何重启
  • 【iOS】 锁
  • uni-app学习笔记十五-vue3页面生命周期(一)
  • Flink核心概念小结
  • 《软件工程》第 14 章 - 持续集成
  • 大模型 Agent 中的通用 MCP 机制详解
  • Navicat 17 SQL 预览时表名异常右键表名,点击设计表->SQL预览->另存为的SQL预览时,表名都是 Untitled。
  • Orpheus-TTS:AI文本转语音,免费好用的TTS系统
  • Python爬虫实战:研究Goose框架相关技术
  • webpack优化方法
  • STM32 Keil工程搭建 (手动搭建)流程 2025年5月27日07:42:09