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

LeetCode-题目整理【5】:O(1) 时间插入、删除和获取随机元素

RandomizedSet结构体存在切片和哈希表的原因:

  1. 变长数组由于可以根据下标定位到特定元素,因此可以在 O(1)的时间内完成获取随机元素操作,但是由于无法在 O(1) 的时间内判断元素是否存在,因此不能在 O(1) 的时间内完成插入和删除操作。

  2. 哈希表可以在 O(1) 的时间内判断元素是否存在,因此可以在 O(1)的时间内完成插入和删除操作,但是不可以根据下标定位到特定元素,因此不能在 O(1) 的时间内完成获取随机元素操作。

    为了满足插入、删除和获取随机元素操作的时间复杂度都是 O(1),需要将变长数组和哈希表结合,变长数组中存储元素,哈希表中存储每个元素在变长数组中的下标。

  1. O(1) 时间插入、删除和获取随机元素
    实现RandomizedSet 类:
    RandomizedSet() 初始化 RandomizedSet 对象
    bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。
    bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false 。
    int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
    你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1) 。
    示例:
    输入
    [“RandomizedSet”, “insert”, “remove”, “insert”, “getRandom”, “remove”, “insert”, “getRandom”]
    [[], [1], [2], [2], [], [1], [2], []]
    输出
    [null, true, false, true, 2, true, false, 2]
    解释
    RandomizedSet randomizedSet = new RandomizedSet();
    randomizedSet.insert(1); // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
    randomizedSet.remove(2); // 返回 false ,表示集合中不存在 2 。
    randomizedSet.insert(2); // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
    randomizedSet.getRandom(); // getRandom 应随机返回 1 或 2 。
    randomizedSet.remove(1); // 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
    randomizedSet.insert(2); // 2 已在集合中,所以返回 false 。
    randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
type RandomizedSet struct {nums    []intindices map[int]int
}func Constructor() RandomizedSet {return RandomizedSet{nums:    make([]int, 0),indices: make(map[int]int),}
}func (this *RandomizedSet) Insert(val int) bool {if _, ok := this.indices[val]; ok {return false}// 在变长数组的末尾添加 valthis.nums = append(this.nums, val)//在添加 val 之前的变长数组长度为 val所在下标 index,将 val和下标 index 存入哈希表;// 因为要保证插入的值唯一,因此需要放在key的位置this.indices[val] = len(this.nums) - 1return true
}func (this *RandomizedSet) Remove(val int) bool {idx, ok := this.indices[val]if !ok {return false}lastIdx := len(this.nums) - 1lastVal := this.nums[lastIdx]this.nums[idx] = lastValthis.indices[lastVal] = idxdelete(this.indices, val)this.nums = this.nums[:lastIdx]return true
}func (this *RandomizedSet) GetRandom() int {randIdx := rand.Intn(len(this.nums))return this.nums[randIdx]
}// 变长数组可以在 O(1)的时间内完成获取随机元素操作,但是由于无法在 O(1) 的时间内判断元素是否存在,因此不能在 O(1) 的时间内完成插入和删除操作。哈希表可以在 O(1)的时间内完成插入和删除操作,但是由于无法根据下标定位到特定元素,因此不能在 O(1) 的时间内完成获取随机元素操作。
//为了满足插入、删除和获取随机元素操作的时间复杂度都是 O(1),需要将变长数组和哈希表结合,变长数组中存储元素,哈希表中存储每个元素在变长数组中的下标。/**1. Your RandomizedSet object will be instantiated and called as such:2. obj := Constructor();3. param_1 := obj.Insert(val);4. param_2 := obj.Remove(val);5. param_3 := obj.GetRandom();*/
  1. 插入操作时,首先判断 val是否在哈希表中,如果已经存在则返回 false,如果不存在则插入 val,操作如下:
    在变长数组的末尾添加 val;
    在添加 val之前的变长数组长度为 val所在下标 index,将 val\textit{val}val 和下标 index 存入哈希表;
    返回 true。
  2. 删除操作时,首先判断 val是否在哈希表中,如果不存在则返回 false,如果存在则删除 val,操作如下:
    从哈希表中获得 val的下标 index;
    将变长数组的最后一个元素 last移动到下标 index处,在哈希表中将 last 的下标更新为 index;
    在变长数组中删除最后一个元素,在哈希表中删除 val;
    返回 true。

删除操作的重点在于将变长数组的最后一个元素移动到待删除元素的下标处,然后删除变长数组的最后一个元素。该操作的时间复杂度是 O(1),且可以保证在删除操作之后变长数组中的所有元素的下标都连续,方便插入操作和获取随机元素操作。
(相当于把nums的最后一个元素lastval代替val在数组中的位置,同时也更新哈希表中lastval的值,最后截取数组,不要最后一个元素)

  1. 获取随机元素操作时,由于变长数组中的所有元素的下标都连续,因此随机选取一个下标,返回变长数组中该下标处的元素。

相关文章:

LeetCode-题目整理【5】:O(1) 时间插入、删除和获取随机元素

RandomizedSet结构体存在切片和哈希表的原因: 变长数组由于可以根据下标定位到特定元素,因此可以在 O(1)的时间内完成获取随机元素操作,但是由于无法在 O(1) 的时间内判断元素是否存在,因此不能在 O(1) 的时间内完成插入和删除操作…...

服务器感染了.wis[[Rast@airmail.cc]].wis勒索病毒,如何确保数据文件完整恢复?

导言: 在当今数字化的时代,恶意软件攻击已经变得越来越复杂和狡猾,[[MyFilewaifu.club]].wis [[backupwaifu.club]].wis[[Rastairmail.cc]].wis勒索病毒是其中的一种新威胁。本文91数据恢复将深入介绍[[MyFilewaifu.club]].wis [[backupwaif…...

ContentNegotiationManagerFactoryBean 内容协商

一.什么是内容协商 简单点说,就是同一资源,可以有多种表现形式,比如xml、json等,具体使用哪种表现形式,是可以协商的。 这是RESTfull的一个重要特性,Spring Web MVC也支持这个功能。 1.Spring MVC REST是如何决定采用…...

html css js 开发一个猜数字游戏

以下是一个使用HTML、CSS和JS开发的简单猜数字游戏的示例&#xff1a; HTML代码&#xff1a; <!DOCTYPE html> <html> <head><title>猜数字游戏</title><link rel"stylesheet" type"text/css" href"style.css&quo…...

HDD 东山再起,单块 30TB 起步新品想要颠覆储存行业

不得不承认&#xff0c;这年头机械硬盘&#xff08;HDD&#xff09;是越来越不受待见了。 体积大&#xff0c;耗电高&#xff0c;速度慢等多年祖传特点无不脱离当前消费者所追求的轻量化&#xff0c;高性能。 个人消费市场不约而同选择全面奔向固态硬盘&#xff08;SSD&#x…...

【网络安全】-基本工具msf

secure 1、有此漏洞的目标主机2、无此漏洞的目标主机&#xff08;常用&#xff09; ps.本着兴趣爱好&#xff0c;加强电脑的安全防护能力&#xff0c;并严格遵守法律和道德规范。msf&#xff08;metasploit framework&#xff09;是一个开源的渗透测试框架&#xff0c;用于开发…...

Vue3的ref和reactive

目录 1、ref的基本使用 2、reactive的基本使用 3、ref操作dom 4、ref与reactive的异同 1、ref的基本使用 ref创建数据可以是基本类型也可以是引用类型 ref函数创建响应式数据&#xff0c;返回值是一个对象 模版中使用ref数据,省略.value&#xff0c;js代码中不能省略 获…...

Flink编程——风险欺诈检测

Flink 风险欺诈检测 文章目录 Flink 风险欺诈检测背景准备条件FraudDetectionJob.javaFraudDetector.java 代码分析执行环境创建数据源对事件分区 & 欺诈检测输出结果运行作业欺诈检测器 欺诈检测器 v1&#xff1a;状态欺诈检测器 v2&#xff1a;状态 时间完整的程序期望的…...

Day37 贪心算法 part06 738. 单调递增的数字 968. 监控二叉树

贪心算法 part06 738. 单调递增的数字 968. 监控二叉树 738. 单调递增的数字 class Solution { public:int monotoneIncreasingDigits(int n) {string strNum to_string(n);int tag strNum.size();for(int i strNum.size()-1; i>1; i--){if(strNum[i]<strNum[i-1]){…...

SpringBoot Redis入门(四)——Redis单机、哨兵、集群模式

单机模式&#xff1a;单台缓存服务器&#xff0c;开发、测试环境下使用&#xff1b;哨兵模式&#xff1a;主-从模式&#xff0c;提高缓存服务器的高可用和安全性。所有缓存的数据在每个节点上都一致。每个节点添加监听器&#xff0c;不断监听节点可用状态&#xff0c;一旦主节点…...

获取数组中的第一个、第二个、第三个......元素

常规操作可以直接使用索引&#xff08;下标&#xff09;获取&#xff1a; const arr [5,8,6,9,10] const first arr[0] //5 const second arr[1] //8 const third arr[2] //6 不使用索引&#xff0c;如何获取&#xff1a; const [first] [5,8,6,9,10] //…...

前端面试题(持续更新~~)

文章目录 一、基础1、数组常用的方法2、数组有哪几种循环方式&#xff1f;分别有什么作用&#xff1f;3、字符串常用的方法4、原型链5、闭包6、常见的继承7、cookie 、localstorage 、 sessionstrorage区别8、数组去重方法9、http 的请求方式10、数据类型的判断方法11、cookie …...

ubuntu下无法访问和ping通github的一种解决方法

近期在ubuntu下突然无法访问github了&#xff0c;ping也无法ping通&#xff0c;尝试过更换不同的网络也无济于事。后来在https://blog.csdn.net/weixin_48544978/article/details/133899687 这个文章中找到了解决办法。 运气比较好&#xff0c;只按照文章中的第一步将http://…...

C#,入门教程(28)——文件夹(目录)、文件读(Read)与写(Write)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(27)——应用程序&#xff08;Application&#xff09;的基础知识https://blog.csdn.net/beijinghorn/article/details/125094837 C#知识比你的预期简单的多&#xff0c;但也远远超乎你的想象&#xff01; 与文件相关的知识&#xf…...

开源大数据集群部署(六)Keytab文件生成

作者&#xff1a;櫰木 Keytab文件用于在不输入密码的情况下对主体&#xff08;用户或服务&#xff09;进行身份验证。以下是创建Kerberos身份验证的步骤。 1、创建keytab文件 除了使用明文密码登录之外&#xff0c;Kerberos还可以使用keytab密码文件登陆&#xff0c;现在为te…...

图神经网络X项目|基于图神经网络的电商行为的预测(5%)

文章目录 Jupyter Notebook 学习人工智能的好帮手数据集数据集下载数据集调用数据集应用技巧——获取不重复的编号数据集应用技巧——随机采样数据集应用技巧——抽取前N项进行模拟测试 数据集构建技巧一——查看数据集构建进度 Jupyter Notebook 学习人工智能的好帮手 【Jupy…...

仰暮计划|“说是操场,那就是个土坡,我们在那儿上边种种树啊,拔拔草,有的时候还会有同学来喂喂羊啥的,这都是我们的娱乐”

我是1948年农历二月份在河南省许昌市五女店镇的一个乡村里边出生的。从我记事的时候&#xff0c;中华人民共和国就已经成立了。当时是好多年&#xff0c;经历了三大改造呀、生产队呀、大队呀&#xff0c;乱七八糟的很多&#xff0c;估计你们现在这些孩子们啊&#xff0c;都没有…...

Java【代码 16】将word、excel文件转换为pdf格式和将pdf文档转换为image格式工具类分享

1.感谢 感谢小伙伴儿的分享&#xff1a; ● 不羁 ● 郭中天 整合调整后的工具类Gitee地址&#xff1a;https://gitee.com/yuanzhengme/java_application_aspose_demo 2.包含的工具类 ● WordToPdfUtil用于将word文档转换为pdf格式的工具类 ● ExcelToPdfUtil用于将excel文档…...

8亿日活的抖音,用“自我设限”谋求长期主义

文&#xff5c;新熔财经 作者&#xff5c;寒蝉鸣 随着手机近乎全民化的普及&#xff0c;在互联网上“冲浪”的人是越来越多了。 根据QuestMobile发布的《中国互联网核心趋势年度报告&#xff08;2023&#xff09;》&#xff0c;2023年&#xff0c;中国移动互联网月活跃用户规…...

Final Cut Pro v10.7.1中文版 专业级视频剪辑软件 兼容M

Final Cut Pro 是 macOS平台上最好的视频剪辑软件&#xff0c;基于Cocoa编写&#xff0c;支持多路多核心处理器&#xff0c;支持GPU加速&#xff0c;支持后台渲染&#xff0c;可编辑从标清到4K的各种分辨率视频&#xff0c;ColorSync管理的色彩流水线则可保证全片色彩的一致性。…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...