Day16-递归&回溯-有重复数组的子集
时间:2022-06-25
本文章向大家介绍Day16-递归&回溯-有重复数组的子集,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一 唠嗑
其实今天这道题本应该在昨天的,第二篇文章中的,奈何需求多而紧,着实没时间写第二篇文章了,你们可不要以为我是划水啊
熬过这周,下周的文章一定高产
二 上题!
Q:已知一个数组,可能有重复元素,求所有的子集,要求不能重复。
举例:有nums = [2, 1, 2, 2]
则我需要return [[], [1], [1, 2], [1, 2, 2], [1, 2, 2, 2], [2], [2, 2], [2, 2, 2]]
需要注意,[2, 1, 2] 和 [1, 2, 2] 是重复的子集,不能都返回。
三 冷静分析
在昨天那道题的思路下,我们思考:
这道题复杂在:
对于【2,1,2,2】在回溯过程中
取下标0,1,3,是【2,1,2】
取下标0,1,2,是【2,1,2】
取下标1,2,3, 是【1,2,2】
这三组子集,均代表一种情况,故只能出现一次,怎么解决?
思路:
对于原数组【2,1,2,2】,将其排序后为【1,2,2,2】
此时无论怎么取下标,只能出现【1,2,2】这样的情况
会出现三次这种情况?怎么解决?
利用c++STL中的集合set去重的特性,我们只计入第一次的【1,2,2】
即 排序 + 去重
四 完整代码及注释
//
// Created by renyi on 2019/6/26.
//
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
void subsetsWithDuplicate(int i, vector<int> &nums, vector<int> &item, vector<vector<int>> &result, set<vector<int>> &res_set){
if (i >= nums.size()){
return;
}
item.push_back(nums[i]);
if (res_set.find(item) == res_set.end()){//集合res_set中没有item,即去重逻辑,当第二次取到【1,2,2】时,将不会走if逻辑,result也不会追加item了,实现去重
result.push_back(item);
res_set.insert(item);
}
subsetsWithDuplicate(i + 1, nums, item, result, res_set);
item.pop_back();
subsetsWithDuplicate(i + 1, nums, item, result, res_set);
}
vector<vector<int>> subsets(vector<int> &nums){
vector<int> item;
vector<vector<int>> result;
set<vector<int>> res_set;//去重的集合,需要将数组元素item插入集合中
sort(nums.begin(), nums.end());//先将数组排序
result.push_back(item);//结果中加入空集
subsetsWithDuplicate(0, nums, item, result, res_set);
return result;
}
int main(){
vector<int> nums;
nums.push_back(2);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2);
vector<vector<int>> result;
result = subsets(nums);
for (int i = 0; i < result.size(); i++) {
if (result[i].size() == 0){
printf("[]");
}
for (int j = 0; j < result[i].size(); j++) {
printf("[%d]", result[i][j]);
}
printf("n");
}
return 0;
}
运行结果
这里我还是建议在21行打断点后单步,观察集合和item的联合变化
随手一截,给出一个瞬时条件下的集合值
- 讨厌算法的程序员 2 - 证明算法的正确性
- Day4上午解题报告
- [编程经验] Python正则表达式
- Day4下午解题报告
- linux下 Error running javac compiler
- 讨厌算法的程序员 1 - 插入排序
- Linux下使用ssh密钥实现无交互备份
- [编程经验] Python中的continue和break语句
- 洛谷 P3386 【模板】二分图匹配 Dinic版
- [编程经验] 拉勾网爬虫数据的后续处理
- Linux下使用rsync实现文件备份
- 【干货】基于TensorFlow卷积神经网络的短期股票预测
- [编程经验] 基于bs4的拉勾网AI相关工作爬虫实现
- [编程经验] 链家23个全国主要城市的现房数据分析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 工作记录二: 记录一次简单的SQL优化过程
- Elastic Search
- [数据结构与算法] 图结构
- [数据结构与算法]赫夫曼树与赫夫曼编码
- [数据结构与算法] 查找算法
- Kafka——分布式的消息队列
- Scala——多范式, 可伸缩, 类似Java的编程语言
- Storm——分布式实时流式计算框架
- Vue实现复制excel表格内容粘贴至网页
- Sqoop——将关系数据库数据与hadoop数据进行转换的工具
- Sqoop导入数据时异常java.net.ConnectException: Connection refused
- Flume——高可用的、高可靠的、分布式日志收集系统
- Hadoop技术(三)数据仓库工具Hive
- Hadoop技术(一)分布式文件系统HDFS
- Docker技术( 容器虚拟化技术 )