【哈希映射】【 哈希集合】 381. O(1) 时间插入、删除和获取随机元素 - 允许重复

作者推荐

视频算法专题

本文涉及知识点

哈希映射 哈希集合

LeetCode 381. O(1) 时间插入、删除和获取随机元素 - 允许重复

RandomizedCollection 是一种包含数字集合(可能是重复的)的数据结构。它应该支持插入和删除特定元素,以及删除随机元素。
实现 RandomizedCollection 类:
RandomizedCollection()初始化空的 RandomizedCollection 对象。
bool insert(int val) 将一个 val 项插入到集合中,即使该项已经存在。如果该项不存在,则返回 true ,否则返回 false 。
bool remove(int val) 如果存在,从集合中移除一个 val 项。如果该项存在,则返回 true ,否则返回 false 。注意,如果 val 在集合中出现多次,我们只删除其中一个。
int getRandom() 从当前的多个元素集合中返回一个随机元素。每个元素被返回的概率与集合中包含的相同值的数量 线性相关 。
您必须实现类的函数,使每个函数的 平均 时间复杂度为 O(1) 。
注意:生成测试用例时,只有在 RandomizedCollection 中 至少有一项 时,才会调用 getRandom 。
示例 1:
输入
[“RandomizedCollection”, “insert”, “insert”, “insert”, “getRandom”, “remove”, “getRandom”]
[[], [1], [1], [2], [], [1], []]
输出
[null, true, false, true, 2, true, 1]

解释
RandomizedCollection collection = new RandomizedCollection();// 初始化一个空的集合。
collection.insert(1); // 返回 true,因为集合不包含 1。
// 将 1 插入到集合中。
collection.insert(1); // 返回 false,因为集合包含 1。
// 将另一个 1 插入到集合中。集合现在包含 [1,1]。
collection.insert(2); // 返回 true,因为集合不包含 2。
// 将 2 插入到集合中。集合现在包含 [1,1,2]。
collection.getRandom(); // getRandom 应当:
// 有 2/3 的概率返回 1,
// 1/3 的概率返回 2。
collection.remove(1); // 返回 true,因为集合包含 1。
// 从集合中移除 1。集合现在包含 [1,2]。
collection.getRandom(); // getRandom 应该返回 1 或 2,两者的可能性相同。

提示:
-231 <= val <= 231 - 1
insert, remove 和 getRandom 最多 总共 被调用 2 * 105
当调用 getRandom 时,数据结构中 至少有一个 元素

哈希

用向量记录值,追加的时候时间复杂度是O1),删除是O(n)。可以将要删除的元素和尾元素互换,然后删除。
unordered_map<int, unordered_set> m_valueIndex; 记录各值在m_nums中的下标。
注意
要删除的元素就是末尾,要特殊处理。否则会删除下标失败,而多一个下标。

代码

核心代码

class RandomizedCollection {
public:RandomizedCollection() {srand(time(nullptr));std::cout << "==" << std::endl;}bool insert(int val) {bool b = m_valueIndex[val].empty();m_valueIndex[val].emplace(m_nums.size());m_nums.emplace_back(val);std::cout << m_nums.size() << std::endl;return b;}bool remove(int val) {if (m_valueIndex[val].empty()){return false;}const int delIndex = *m_valueIndex[val].begin();m_valueIndex[val].erase(m_valueIndex[val].begin());const int endValue = m_nums.back();if (m_valueIndex[endValue].count(m_nums.size() - 1)){m_valueIndex[endValue].erase(m_nums.size() - 1);m_valueIndex[endValue].emplace(delIndex);m_nums[delIndex] = endValue;}m_nums.pop_back();std::cout << "del " << m_nums.size() << std::endl;return true;}int getRandom() {std::cout << "getRandom " << m_nums.size() << std::endl;return m_nums[rand() % m_nums.size()];}unordered_map<int, unordered_set<int>> m_valueIndex;vector<int> m_nums;
};

2023年5月

class RandomizedCollection {
public:
RandomizedCollection() {
srand(time(nullptr));
}
bool insert(int val) {
m_mValueIndexs[val].emplace(m_iSize);
m_arr[m_iSize] = val;
m_iSize++;
return 1 == m_mValueIndexs[val].size();
}
bool remove(int val) {
if (m_mValueIndexs.count(val))
{
int index = *m_mValueIndexs[val].begin();
m_mValueIndexs[val].erase(index);
Erase(index);
if (m_mValueIndexs[val].empty())
{
m_mValueIndexs.erase(val);
}
return true;
}
return false;
}
int getRandom() {
int index = rand() % m_iSize;
return m_arr[index];
}
void Erase(int index)
{
if (m_iSize - 1 == index)
{
m_iSize–;
return;
}
const int iEndValue = m_arr[m_iSize - 1];
m_mValueIndexs[iEndValue].erase(m_iSize - 1);
m_mValueIndexs[iEndValue].insert(index);
std::swap(m_arr[m_iSize - 1], m_arr[index]);
m_iSize–;
}
std::unordered_map<int, std::unordered_set> m_mValueIndexs;
int m_arr[1000 * 200];
int m_iSize = 0;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 **C+

+17**
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

【java/image】将指定路径下所有的png图片进行反色处理

【需求】 在桌面上有若干png图片&#xff0c;是使用截图软件FSCapture7.6对通达信的K线图截图而得&#xff0c;在打印这些K线图前&#xff0c;需要将它们进行反色处理。 【代码】 package test240313;import java.awt.image.BufferedImage; import java.awt.image.ByteLooku…

express-generator生成nodejs服务基本骨架

1. 安装 express-generator 构建工具 npm install -g express-generator 2. 新建express项目 express my-node-server // my-node-server是项目名 3. 初始化后的项目文件的目录结构如下 app.js 应用的主入口 bin 启动脚本 node_modules 依赖的模块 package.json node 模块…

python爬虫实战——小红书

目录 1、博主页面分析 2、在控制台预先获取所有作品页的URL 3、在 Python 中读入该文件并做准备工作 4、处理图文类型作品 5、处理视频类型作品 6、异常访问而被中断的现象 7、完整参考代码 任务&#xff1a;在 win 环境下&#xff0c;利用 Python、webdriver、JavaS…

<.Net>VisaulStudio2022下用VB.net实现socket与汇川PLC进行通讯案例(Eazy521)

前言 此前&#xff0c;我写过一个VB.net环境下与西门子PLC通讯案例的博文&#xff1a; VisaulStudio2022下用VB.net实现socket与西门子PLC进行通讯案例&#xff08;优化版&#xff09; 最近项目上会用到汇川PLC比较多&#xff0c;正好有个项目有上位机通讯需求&#xff0c;于是…

InnoDB对MVCC的实现

MVCC是啥&#xff1f; (Multiversion Concurrency Control) 多版本并发控制 是个方法&#xff0c;是个思想。 解决多并发事务操作同一数据库数据&#xff0c;数据保持一致的问题。 怎么做&#xff1a;每个数据行上维护多个版本 当一个事务要对数据进行修改&#xff0c;为该事…

mysql转达梦的python脚本

mysql_ddl&#xff1a; CREATE TABLE ops_app_import (id char(32) NOT NULL COMMENT 主键ID,pkg_name varchar(255) NOT NULL DEFAULT COMMENT 导入包名称,pkg_md5 varchar(32) NOT NULL COMMENT 导入包md5值,backup_pkg_name varchar(255) DEFAULT COMMENT 备份包名称,bac…

[剪藏] - 由哇哈哈和农夫山泉所想到的

哇哈哈和农夫山泉的缠斗最近冒出来一个有趣的点&#xff1a;营销大于内容的胜利。 具体来说是这样的&#xff1a;农夫山泉很多年前做广告&#xff0c;说纯净水没有矿物质&#xff0c;长期喝是不利于人体健康的。农夫还做了个营销的对比实验&#xff0c;大概是用矿泉水养水仙花&…

龙芯杯赛道-学习过程记录

Preface&免责声明&#xff1a; 由于参赛资料企业并未开源&#xff0c;所以我不能开放出有关参赛的资料 但是我会在这里记录参赛时看不懂的一系列知识补充 ------------------------------------------------------------------------------------------------------- TSEN…

音视频开发之旅(75)- AI数字人进阶--GeneFace++

目录 1.效果展示和玩法场景 2.GeneFace原理学习 3.数据集准备以及训练的过程 5.遇到的问题与解决方案 6.参考资料 一、效果展示 AI数字人进阶--GeneFace&#xff08;1&#xff09; AI数字人进阶--GeneFace&#xff08;2&#xff09; 想象一下&#xff0c;一个专为你打造的…

前端算法 - 查找

1 二分查找 /*** param {number[]} nums* param {number} target* return {number}*/ var search function (nums, target) {let left 0, right nums.length - 1while (left < right) {let mid Math.floor((left right) / 2)if (target < nums[mid]) {right mid -…

为什么 VSCode 不用 Qt 而要用 Electron?

为什么 VSCode 不用 Qt 而要用 Electron? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Qt 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&am…

Python基础课堂最后一课23——正则对象

文章目录 前言一、正则对象是什么&#xff1f;二、正则表达式基本分类1.普通字符2.元字符 总结 前言 很开心能和你们一些学习进步&#xff0c;在这一个多月的时间中&#xff0c;是你们让我坚持了下来&#xff0c;完成了python基础课堂编写&#xff0c;不管如何&#xff0c;我们…

C语言学习(第二十课)初识函数5(函数递归2)

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<string.h> //编写函数&#xff0c;不允许创建临时变量&#xff0c;求字符串长度 ///1、可以使用临时变量的写法&#xff1a; //int my_strlen(char* str) //{ // int count 0; // while (*s…

安卓Java面试题 121- 130

131. Android垃圾回收机制和程序优化System.gc( ) ?垃圾收集算法的核心思想:对虚拟机的可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,则称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。 JVM进行次GC的频率很高…

Linux系统——Nginx脚本拦截拓展

可能会有些无聊的人对服务器的Nginx服务进行恶意访问网站、API接口&#xff0c;会影响到用户的体验&#xff0c;我们可以做一个简单的脚本对恶意访问的IP做一个有效的拦截&#xff0c;揪出这些IP地址&#xff0c;然后将其进行禁用。 在Nginx的conf目录下新建一个blockip.conf文…

Python(C_Cpp)分析模拟Arduino和Raspberry Pi(单板机)CAN总线和车载单元测试

要点 CAN总线释义&#xff1a;物理层结构&#xff0c;数据帧&#xff0c;数据交换&#xff0c;总线接口物理模块。一对Arduino CAN &#xff08;Arduino C 处理&#xff09;总线项目&#xff1a; 发送端发送随机数据&#xff0c;接收端接收并计算。发送端点动信号&#xff0c;…

certificate has expired or is not yet valid:npm和node证书过期问题

在 1 月 22 日&#xff0c;淘宝原镜像域名&#xff08;registry.npm.taobao.org&#xff09;的 HTTPS 证书正式到期。如果想要继续使用&#xff0c;需要将 npm 源切换到新的源&#xff08;registry.npmmirror.com&#xff09;&#xff0c;否则会报错。 解决方案切换到新的源&a…

HTML表单

本文章属于学习笔记&#xff0c;在https://www.freecodecamp.org/chinese/learn/2022/responsive-web-design/中练习 四、HTML表单 CSS 1、vh单位表示视口高度&#xff0c;等于视口高度的1%。这使得它相对于视口高度。height:100vh; 2、设置 body 的默认 margin 为 0 来重置…

【掌握版本控制:Git 入门与实践指南】远程操作|标签管理

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;泥中に咲く—ウォルピスカーター 0:34━━━━━━️&#x1f49f;──────── 4:46 &#x1f504; ◀️ ⏸ ▶…

汽车IVI中控开发入门及进阶(十三):语音识别

前言: IVI中控上的语音识别,在目前市场上也是非常显眼的一个创新,大幅改变了传统IVI的操作习惯。 语音识别Speech recognition,也称为自动语音识别(ASR)、计算机语音识别或语音到文本,是一种使程序能够将人类语音处理成书面格式的能力。 语音识别Speech recognition是计…