leetcode:380. 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 。

提示:

  • -231 <= val <= 231 - 1
  • 最多调用 insertremove 和 getRandom 函数 2 * 105 次
  • 在调用 getRandom 方法时,数据结构中 至少存在一个 元素。

步骤1:问题定义及输入输出条件

问题性质:
该题目要求实现一个数据结构RandomizedSet,可以高效地执行以下操作:

  1. 插入:如果元素不存在,将其插入集合。
  2. 删除:如果元素存在,将其从集合中删除。
  3. 随机获取元素:随机返回集合中的一个元素,且每个元素有相同的概率被返回。

输入输出条件:

  • insert(int val):如果val不存在于集合中,则插入该元素并返回true;如果存在,则返回false
  • remove(int val):如果val存在于集合中,删除该元素并返回true;如果不存在,返回false
  • getRandom():随机返回集合中的一个元素,要求每个元素的返回概率相同。

限制与边界条件:

  • 数据范围:val 取值范围为 [-2^31, 2^31-1],函数调用次数最多为 2*10^5
  • 调用 getRandom() 时,保证集合中至少存在一个元素。

边界条件:

  1. 空集合remove时如果元素不在集合中,或者对空集合调用getRandom可能会产生边界错误。
  2. 频繁操作:高频调用insertremovegetRandom,每次操作的平均时间复杂度需为O(1)

步骤2:解题思路与算法设计

目标:

  • 插入、删除和获取随机元素的平均时间复杂度为O(1)

算法设计:

  1. 数据结构选择:

    • 哈希表 (unordered_map) + 动态数组 (vector)
      • 使用一个哈希表 map<int, int> 来存储元素到其在数组中的位置的映射。
      • 使用一个动态数组 vector<int> 存储元素值。
      • 这样在插入和删除时,都可以保持O(1)的复杂度,并且可以利用数组支持O(1)时间复杂度的随机访问。
  2. 操作细节:

    • insert(val)
      • 检查val是否存在于哈希表中。如果不存在,插入到数组末尾,并更新哈希表,时间复杂度为O(1)
    • remove(val)
      • 通过哈希表定位val在数组中的位置。为了保持删除操作的O(1),我们将待删除的元素与数组末尾元素交换,然后删除末尾元素,并更新哈希表。
    • getRandom()
      • 直接从数组中随机获取一个元素,时间复杂度为O(1)

时间复杂度分析:

  • insert: 哈希表插入是O(1),动态数组末尾插入是O(1)
  • remove: 哈希表删除是O(1),动态数组末尾删除是O(1)
  • getRandom: 直接从数组中随机访问,时间复杂度为O(1)

步骤3:代码实现

代码注释:

  1. insert(int val):当val不在哈希表中时,将其加入到数组的末尾,并记录其在哈希表中的索引。
  2. remove(int val):先从哈希表中获取待删除元素的位置,将其与数组的最后一个元素交换,再删除最后一个元素,确保删除操作的时间复杂度为O(1)
  3. getRandom():利用数组的随机访问特性,直接生成一个随机索引返回对应的元素。

步骤4:算法优化和启发

通过该问题,我们可以看到如何将多种数据结构结合起来以提升算法效率。哈希表可以实现快速查找,动态数组可以实现高效的随机访问和插入。通过交换和删除末尾元素,可以确保删除操作的O(1)复杂度。

优化启发:

  • 空间效率:虽然结合哈希表和数组可以实现高效的时间复杂度,但需要占用较多的空间。如果数据量非常大,需要权衡时间和空间的平衡。
  • 算法设计思路:此问题展示了如何使用简单的数据结构组合来解决复杂问题,在实际应用中,通过合理的数据结构选择可以极大地提升效率。

步骤5:实际应用场景

该算法可以用于许多需要高效集合操作的场景,比如:

  • 在线游戏服务器:当需要随机选择在线玩家进行匹配时,可以使用该结构存储在线玩家列表并随机选择。
  • 负载均衡:在负载均衡系统中,随机选择服务器进行请求分发,可以通过类似的数据结构实现高效选择和删除。
实际应用示例:负载均衡中的随机服务器选择

在大规模服务器集群中,通常需要从可用的服务器列表中随机选择一台服务器进行任务分发。如果某些服务器挂掉,还需要将其从列表中移除。使用类似RandomizedSet的结构可以高效地管理服务器列表,并快速随机选取可用服务器进行负载均衡。

通过哈希表来快速定位服务器,结合数组来实现随机选择,使得服务器的添加、移除和随机选择都能够在常数时间内完成,提升系统的响应速度和稳定性。

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

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

相关文章

前端框架对比和选择指南

前端框架对比和选择指南 随着 Web 开发技术的快速发展&#xff0c;前端框架已经成为了现代 Web 开发的核心工具之一。它们为开发人员提供了快速构建高效、交互性强的应用的基础。当前流行的前端框架主要包括 React.js、Vue.js 和 Angular.js。在这篇技术博客中&#xff0c;我们…

如何创建一个docker,给它命名,且下次重新打开它

1.创建一个新的docker并同时命名 docker run -it --name one ubuntu:18.04 /bin/bash 这时候我们已经创建了一个docker,并且命名为"one" 2.关闭当前docker exit 3.这时docker已经终止了&#xff0c;我们需要使用它要重新启动 docker start one 4.现在可以重新打…

react crash course 2024(7) react router dom

安装 npm i react-router-dom 引入 import {Route,createBrowserRouter,createRoutesFromElements,RouterProvider} from react-router-dom 在app.jsx const router createBrowserRouter(createRoutesFromElements(<Route index element {<h1>My App</h1>…

基于51单片机的3路电压测量-proteus仿真

地址&#xff1a;https://pan.baidu.com/s/1PG2vzudc1QKHGSBfjPF0eQ 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectron…

金智维KRPA之Excel自动化

Excel自动化操作概述 Excel自动化主要用于帮助各种类型的企业用户实现Excel数据处理自动化&#xff0c;Excel自动化是可以从单元格、列、行或范围中读取数据&#xff0c;向其他电子表格或工作簿写入数据等活动。 通过相关命令&#xff0c;还可以对数据进行排序、进行格式…

QT 界面编程中使用协程

QT 界面编程中使用协程 一、概述二、集成2.1、编译 Acl2.2、将 Acl 库集成到 QT 项目中2.3、开始编写代码2.3.1、QT 程序初始化时初始化 Acl 协程2.3.2、在界面中创建协程2.3.3、界面程序退出前需要停止协程调度2.3.4、在界面线程中下载数据2.3.5、在协程中延迟创建窗口 2.4、效…

[sql-04] 连续出现至少三次的数字

数据准备 CREATE TABLE leecode_01 (id bigint not null AUTO_INCREMENT,num int DEFAULT NULL COMMENT 用户名,primary key(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT leecode(连续出现3次的数字)insert into leecode_01(num) values(12); insert into leecode_01…

C++入门基础 (超详解)

文章目录 前言1. C关键字2. C的第一个程序3. 命名空间3.1 namespace的定义3.2 命名空间的嵌套3.3 命名空间使用3.4 查找优先级总结 4. C输入和输出4.1 标准输入输出 (iostream库)4.2 文件输入输出 (fstream库)4.3 字符串流 (sstream库)4.4 C格式化输出4.5 std::endl和\n的区别 …

废物利用,三百块电脑如何升级并安装双系统便携使用

文章目录 引言最初的配置开始改装更换内存升级硬盘2.5 英寸 sata 固态msata 加装 升级电池其他的升级娱乐大师跑分 双系统安装前提条件设置 Bios安装 win 10安装 Manjaro时间同步问题 屏幕问题黑屏难开 引言 最近浏览 b 站的二手笔记本信息&#xff0c;想要整个二手笔记本玩玩…

imagickd写shell的技术学习

前言 没想到吧哥们&#xff0c;imagickd也能写shell&#xff0c;真是学到了不少&#xff0c;下面会具体分析是如何写shell的 基础知识 Imagick类 参考官方手册https://www.php.net/manual/zh/class.imagick.php 重点关注他的构造方法 (PECL imagick 2, PECL imagick 3) …

c++primer第十三章 类继承

本章内容&#xff1a;单个类就可以提供用于管理对话框的全部资源。通常&#xff0c;类库是以源代码的方式提供的&#xff0c;这意味着可以对其进行修改&#xff0c;以满足需求。但是&#xff0c;C-提供了比修改代码更好的方法来扩展和修改类。这种方法叫作类继承(class inheria…

手机/平板端 Wallpaper 动态壁纸文件获取及白嫖使用指南

Wallpaper 动态壁纸文件获取及使用指南 目录 壁纸文件获取手机 / 平板使用手机 / 平板效果预览注意事项PC/Mac 使用 1. 壁纸文件获取链接 链接&#xff1a;夸克网盘分享 复制链接到浏览器打开并转存下载即可。 &#xff08;主页往期视频的 4K 原图和 mpkg 动态壁纸文件&#xf…

Redis接口访问优化

说明&#xff1a;之前写过一篇使用Redis接口访问的博客&#xff0c;如下。最近有相关需求&#xff0c;把代码拿出来后&#xff0c;做了一些优化&#xff0c;挺有意思的&#xff0c;本文介绍在原基础上 使用Redis实现接口防抖 优化 总的来说&#xff0c;这次使用Redis实现接口…

IDEA 系列产品 下载

准备工作 下载 下载链接&#xff1a;https://www.123865.com/ps/EF7OTd-yVHnH 仅供参考 环境 演示环境&#xff1a; 操作系统&#xff1a;windows10 产品&#xff1a;IntelliJ IDEA 版本&#xff1a;2024.1.2 注意&#xff1a;如果需要其他产品或者版本可以自行下载&#xff0…

ESP32微信小程序SmartConfig配网

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 ESP32&微信小程序SmartConfig配网 前言一、SmartConfig是什么&#xff1f;二、使用乐鑫官方的smart_config例子1.运行照片 三、微信小程序总结 前言 本人是酷爱ESP32S3这…

C++系列-多态

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 多态 多态就是不同类型的对象&#xff0c;去做同一个行为&#xff0c;但是产生的结果是不同的。 比如说&#xff1a; 都是动物叫声&#xff0c;猫是喵喵&#xff0c;狗是汪汪&am…

LC记录二:丑数专题,一文秒解丑数3题

文章目录 263.丑数1264.丑数21201.丑数3 263.丑数1 https://leetcode.cn/problems/ugly-number/description/ 简单题&#xff0c;丑数只包含质因子2、3、5。所以直接使用 n 循环 除 2 3 5最后判断结果是否等于1即可。 代码&#xff1a; class Solution {public boolean isUg…

Java中的顺序控制、分支控制、嵌套分支if-else

if-else 顺序控制分支控制if-else单分支1.基本语法2.说明&#xff1a;3.案例说明4.流程图 双分支1.基本语法2.说明&#xff1a;3.案例说明4.流程图5.练习 多分支1.基本语法2.说明&#xff1a;3.流程图4.练习 嵌套分支1.基本介绍2.基本语法3.练习 顺序控制 1.介绍&#xff1a;程…

AntFlow-Vue3 :一个仿钉钉流程审批,且满足99.8%以上审批流程需求的企业级工作流平台,开源且免费!

在现代企业管理中&#xff0c;流程审批的高效性直接影响到工作的流畅度与生产力。最近&#xff0c;我发现了一个非常有趣的项目—— AntFlow-Vue3 。这个项目不仅提供了一个灵活且可定制的工作流平台&#xff0c;还能让用户以可视化的方式创建和管理审批流程。 如果你是一名前…

【Android 13源码分析】Activity生命周期之onCreate,onStart,onResume-1

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…