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

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();}}
};

相关文章:

  • Claude 4对比Claude 3.7全面评测:2025最新AI模型实测对比
  • Femap许可证与网络安全策略
  • APP广告变现,开发者如何判断对接的广告SDK安全合规?
  • 注意力机制模块代码
  • windows中Redis、MySQL 和 Elasticsearch启动并正确监听指定端口
  • 实时数仓flick+clickhouse启动命令
  • 聊一聊 .NET Dump 中的 Linux信号机制
  • Spark SQL进阶:解锁大数据处理的新姿势
  • 编程规范Summary
  • C++ STL stack容器使用详解
  • 2025 年江西研究生数学建模竞赛题A题电动汽车充电桩共享优化与电网安全协同模型完整思路 模型代码 结果 成品分享
  • 浙大版《Python 程序设计》题目集6-3,6-4,6-5,6-6列表或元组的数字元素求和及其变式(递归解法)
  • C++11 中引入的`final` 关键字作用。
  • python处理signal(信号)
  • 8种使用克劳德4的方法,目前可用随时更新!
  • Map集合(双列集合)
  • Qt QPaintEvent绘图事件painter使用指南
  • lcd-framebuffer驱动开发参考文章
  • 外卖霸王餐支持京东外卖点餐啦~
  • 零基础远程连接课题组Linux服务器,安装anaconda,配置python环境(换源),在服务器上运行python代码【1/3 适合小白,步骤详细!!!】
  • 常州微信网站建设案例/焦作seo公司
  • 淄博做网站哪家好/网络营销推广方案案例
  • wordpress 在线运行/拼多多关键词优化是怎么弄的
  • 河南做网站哪个公司好/百度排名点击软件
  • 优酷网站谁做的/怎么在百度上发布自己的信息
  • 房山网站开发/百度做广告多少钱一天