【C++】每日一题 380 O(1)时间插入,删除和获取随机元素

2024-04-07 11:44

本文主要是介绍【C++】每日一题 380 O(1)时间插入,删除和获取随机元素,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实现RandomizedSet 类:

RandomizedSet() 初始化 RandomizedSet 对象
bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。
bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false 。
int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1) 。

#include <unordered_map>
#include <vector>
#include <cstdlib>class RandomizedSet {
private:std::unordered_map<int, int> valToIndex; // 用于存储值到索引的映射std::vector<int> values; // 用于存储集合中的值public:/** Initialize your data structure here. */RandomizedSet() {}/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */bool insert(int val) {if (valToIndex.find(val) != valToIndex.end()) {return false; // 如果值已经存在,则返回false}values.push_back(val); // 在向量末尾插入新值valToIndex[val] = values.size() - 1; // 更新值到索引的映射return true;}/** Removes a value from the set. Returns true if the set contained the specified element. */bool remove(int val) {if (valToIndex.find(val) == valToIndex.end()) {return false; // 如果值不存在,则返回false}int index = valToIndex[val]; // 获取值在向量中的索引int lastVal = values.back(); // 获取向量中最后一个值values[index] = lastVal; // 将最后一个值移到被删除的位置valToIndex[lastVal] = index; // 更新最后一个值的索引values.pop_back(); // 删除最后一个值valToIndex.erase(val); // 删除值到索引的映射return true;}/** Get a random element from the set. */int getRandom() {int randomIndex = rand() % values.size(); // 生成随机索引return values[randomIndex]; // 返回随机索引处的值}
};

使用了一个 unordered_map 来存储值到索引的映射,以实现 O(1) 时间复杂度的插入和删除操作。同时,使用一个 vector 来存储集合中的值,并且通过将被删除元素与最后一个元素交换,然后再删除最后一个元素的方式来实现 O(1) 时间复杂度的删除操作。最后,getRandom 函数通过生成一个随机索引来随机返回集合中的一个元素。

易错点:
从 nums 向量中删除特定值 val 对应的元素,并且更新 indices 映射,使得其仍然与 nums 同步。以下代码错误示范

nums.erase(nums.begin()+indices[val]);
indices.erase(val);

假设 indices[val] 给出了 val 在 nums 中的索引位置。第一行代码是从 nums 向量中删除这个索引位置的元素,但是删除后,后面的元素会向前移动填补被删除的位置,这就会导致原来在 indices[val] 位置的元素变成了新的 val,而且 val 在 nums 中的位置已经改变了,所以删除 val 对应的索引值并不正确。

正确的做法是通过交换最后一个元素和要删除的元素来实现删除,然后更新映射。这就是下面的代码片段:

int index = indices[val];
int last = nums.back();
nums[index] = last;
indices[last] = index;
nums.pop_back();
indices.erase(val);

这样做的好处是,它避免了在删除元素后重新排序 nums 向量,同时保持了 indices 映射的正确性。

这篇关于【C++】每日一题 380 O(1)时间插入,删除和获取随机元素的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/882508

相关文章

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

docker如何删除悬空镜像

《docker如何删除悬空镜像》文章介绍了如何使用Docker命令删除悬空镜像,以提高服务器空间利用率,通过使用dockerimage命令结合filter和awk工具,可以过滤出没有Tag的镜像,并将... 目录docChina编程ker删除悬空镜像前言悬空镜像docker官方提供的方式自定义方式总结docker

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

Java通过反射获取方法参数名的方式小结

《Java通过反射获取方法参数名的方式小结》这篇文章主要为大家详细介绍了Java如何通过反射获取方法参数名的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、解决方式方式2.1: 添加编译参数配置 -parameters方式2.2: 使用Spring的内部工具类 -

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更