(数组/字符串) 380. O(1) 时间插入、删除和获取随机元素 ——【Leetcode每日一题】

news2025/1/22 21:48:21

❓ 380. O(1) 时间插入、删除和获取随机元素

难度:中等

实现 RandomizedSet 类:

  • RandomizedSet() 初始化 RandomizedSet 对象
  • bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false
  • bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false
  • int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。

你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O ( 1 ) O(1) 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 。

提示

  • − 2 31 < = v a l < = 2 31 − 1 -2^{31} <= val <= 2^{31} - 1 231<=val<=2311
  • 最多调用 insertremovegetRandom 函数 2 ∗ 1 0 5 2 * 10^5 2105
  • 在调用 getRandom 方法时,数据结构中 至少存在一个 元素。

💡思路:哈希表 + 变长数组

哈希表可以在 O ( 1 ) O(1) O(1) 的时间内完成 插入删除 操作,但是由于无法根据下标定位到特定元素,因此不能在 O ( 1 ) O(1) O(1) 的时间内完成 获取随机元素 操作。而数组可以在 O ( 1 ) O(1) O(1) 的时间内完成 获取随机元素 操作。所以使用哈希表加数组:

  • 哈希表记录 加入删除 的数,可以 O ( 1 ) O(1) O(1) 检查是否出现过;
  • 用数组 nums 维护所有数,方便随机取一个数,数组后加入一个数也是 O ( 1 ) O(1) O(1)
  • 哈希表 维护每个数加入时的坐标,以加入的元素 val主键, 以数组 nums 下标为
  • 在要删除的数不是数组最后一个时,与最后一个交换(因为是不在乎顺序的,所以这种交换不影响任何东西),此时要删除的数成为数组最后一个,可以 O ( 1 ) O(1) O(1) 删除。

🍁代码:(C++、Java)

C++

class RandomizedSet {
private:
    unordered_map<int, int> map; //哈希表储存元素值和对应下标,为了访问时实现O(1)
    vector<int> nums;

public:
    RandomizedSet() {

    }
    
    bool insert(int val) {
        if(map.find(val) != map.end()) return false;
        nums.push_back(val);
        map[val] = nums.size() - 1;
        return true;
    }
    
    bool remove(int val) {
        if(map.find(val) == map.end()) return false;
        int idx = nums.size() - 1;
        if(map[val] != idx){
            nums[map[val]] = nums[idx];
            map[nums[idx]] = map[val];
        }
        nums.pop_back();
        map.erase(val);
        return true;
    }
    
    int getRandom() {
        int size = nums.size();
        int random = rand() % size;
        return nums[random];
    }
};

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet* obj = new RandomizedSet();
 * bool param_1 = obj->insert(val);
 * bool param_2 = obj->remove(val);
 * int param_3 = obj->getRandom();
 */

Java

class RandomizedSet {
    static int[] nums = new int[200010];
    Random random = new Random();
    Map<Integer, Integer> map = new HashMap<>();
    int idx = -1;

    public RandomizedSet() {
        
    }
    
    public boolean insert(int val) {
        if(map.containsKey(val)) return false;
        nums[++idx] = val;
        map.put(val, idx);
        return true;
    }
    
    public boolean remove(int val) {
        if(!map.containsKey(val)) return false;
        int loc = map.remove(val);
        if(loc != idx) map.put(nums[idx], loc);
        nums[loc] = nums[idx--];
        return true;
    }
    
    public int getRandom() {
        return nums[random.nextInt(idx + 1)];
    }
}

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet obj = new RandomizedSet();
 * boolean param_1 = obj.insert(val);
 * boolean param_2 = obj.remove(val);
 * int param_3 = obj.getRandom();
 */
🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:
  • 时间复杂度 O ( 1 ) O(1) O(1),初始化和各项操作的时间复杂度都是 O ( 1 ) O(1) O(1)
  • 空间复杂度 O ( n ) O(n) O(n),其中 n 是集合中的元素个数。存储元素的数组和哈希表需要 O ( n ) O(n) O(n) 的空间。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!

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

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

相关文章

私房菜外卖配送商城小程序的作用是什么

私房菜有自己的品牌&#xff0c;也更容易跑出连锁经营体系&#xff0c;由于餐饮行业主要服务本地同城客户&#xff0c;因此在实际经营中对商家来说&#xff0c;怎样实现引流获客、促进到店及转化复购很重要。 传统线下传单、朋友圈推广等方式比较低效&#xff0c;而线上入驻第…

Spring Cloud Gateway实战WebFlux解析请求体及抛出指定错误代码和信息

概述 基于Spring Cloud开发微服务时&#xff0c;使用Spring Cloud原生自带的Gateway作为网关&#xff0c;所有请求都需要经过网关服务转发。 为了防止恶意请求刷取数据&#xff0c;对于业务请求需要进行拦截&#xff0c;故而可在网关服务增加拦截过滤器。基于此&#xff0c;有…

uniapp 事件委托失败 获取不到dataset

问题&#xff1a; v-for 多个span ,绑定点击事件 代码:view里包着一个span, <view class"status-list" tap"search"><span class"status-item" v-for"(key,index) in statusList" :key"index" :data-key"k…

程序员大佬‍被没收三年工资105w?

程序员大佬&#x1f468;&#x1f3fb;‍&#x1f4bb;被没收三年工资105w&#xff1f; 我在CSDN搜了一些关键词并没有找到关于这个事件的信息&#xff0c;发这篇文章主要是想让更多的大佬关注一下这个事情的发展&#xff0c;因此就放了几个图片&#xff0c;具体的大佬们可以去…

【短文】怎么查看自己的Linux是哪个发行版本和哪个版本号

2023年9月29&#xff0c;周三晚上 首先去到etc目录 cd /etc 然后用如下命令查看所有文件 ls 找到类似“XXX-release”的文件 然后用如下命令查看这个文件 cat

NodeMCU ESP8266基于Arduino IDE的开发环境搭建(图文并茂)

文章目录 NodeMCU ESP8266基于Arduino IDE的开发环境搭建&#xff08;手把手教程&#xff09;软件下载官网地址百度云 安装IDE配置基础配置设置开发板 测试串口驱动下载测试用例 总结 NodeMCU ESP8266基于Arduino IDE的开发环境搭建&#xff08;手把手教程&#xff09; 软件下…

力扣每日一题(+日常水几道题)

每日一题1333. 餐厅过滤器 - 力扣&#xff08;LeetCode&#xff09; 简单的按规则排序,去除几个不满足的条件然后排序返回即可 #include<algorithm> class Solution { public:vector<int> filterRestaurants(vector<vector<int>>& restaurants, …

涉及多条件查询 使用mybatispluse的解决方法EasyCaptcha图形验证码工具

登录中遇到账号和密码去数据库中查询因为查询是多条件的 所以需要使用QueryWrapper中allEq 而allEq如何添加条件使用map 位于mybatisplus的条件构造器的使用 条件构造器 | MyBatis-Plus QueryWrapper<User> wrapper new QueryWrapper<>();Map<String, Object&g…

rust所有权

一、堆和栈 栈和堆都是程序运行时使用的内存&#xff0c;但是它们的结构不同。 1.栈 栈&#xff0c;英文是stack。是内存的一段区域。 栈是后进先出形式的。就像薯片桶&#xff0c;先放进去的一片只能后拿出来。 栈上存储的数据大小必须是已知且固定的。也就是说如果一个变量…

独立站引流,如何在Reddit进行营销推广?

Reddit是目前最被忽视却最具潜力的社交媒体营销平台之一&#xff0c;它相当于国内的百度贴吧&#xff0c;是美国最大的论坛&#xff0c;也是美国第五大网站&#xff0c;流量仅次于Google、Youtube、Facebook以及亚马逊。 如果会玩&#xff0c;Reddit也可以跟其他的社交媒体营销…

Ubuntu安装Oracle JDK

文章目录 下载JDK安装Oracle JDK验证安装 下载JDK Oracle JDK需要从Oracle的官方网站下载&#xff0c;访问Oracle的官方网站并下载所需版本的JDK。 https://www.oracle.com/java/technologies/downloads/#java17 安装Oracle JDK 2.1. 下载.tar.gz文件后&#xff0c;移动到适…

一、2023.9.27.C++基础.1

回答问题一定要有逻辑性&#xff0c;我将从 这个技术是什么&#xff1f; 为什么要有这个技术&#xff1f; 这个技术底层是怎么实现的&#xff1f; 这个技术的优点缺点&#xff1f; 这个技术所适合的使用场景&#xff1f; 以下五个方面来回答问题。 文章目录 一、C基础部分&…

自动化测试-友好的第三方库

目录 mock furl coverage deepdiff pandas jsonpath 自动化测试脚本开发中&#xff0c;总是会遇到各种数据处理&#xff0c;例如MOCK、URL处理、JSON数据处理、结果断言等&#xff0c;也会遇到所采用的测试框架不能满足当前需求&#xff0c;这些问题都需要我们自己动手解…

Element UI搭建首页导航和左侧菜单以及Mock.js和(组件通信)总线的运用

目录 前言 一、Mock.js简介及使用 1.Mock.js简介 1.1.什么是Mock.js 1.2.Mock.js的两大特性 1.3.Mock.js使用的优势 1.4.Mock.js的基本用法 1.5.Mock.js与前端框架的集成 2.Mock.js的使用 2.1安装Mock.js 2.2.引入mockjs 2.3.mockjs使用 2.3.1.定义测试数据文件 2…

多元异构、绿色节能,揭秘浪潮计算机基础技术研究与整机柜设计思路

出品 | CSDN 云计算 数字化转型、云计算 技术与应用的爆发&#xff0c;数据中心从传统 CPU 为核心&#xff0c;变为 CPU、GPU、ASIC、FPGA、DPU 等等多种硬件与芯片架构、多元算力并存的阶段。对于企业来说&#xff0c;数字化转型中算力就是生产力&#xff0c;底层算力底座可能…

可信执行环境(Tee)入门综述

SoK: Hardware-supported Trusted Execution Environments [ArXiv22] 摘要引言贡献 范围系统和威胁模型系统模型威胁模型共存飞地对手无特权软件对手系统软件对手启动对手外围对手结构对手侵入性对手 关于侧信道攻击的一点注记 VERIFIABLE LAUNCH信任根&#xff08;RTM&#xf…

jvm深入研究文档--jvm分区以及职责

Java虚拟机&#xff08;JVM&#xff09;主要包括以下几个区域&#xff1a; 方法区&#xff08;Method Area&#xff09;&#xff1a;这个区域存储已被加载的类信息&#xff0c;常量&#xff0c;静态变量&#xff0c;即时编译器编译后的代码等数据。方法区是所有线程共享的。在…

C. Card Game

题目&#xff1a;样例&#xff1a; 输入 4 4 -4 1 -3 5 4 1 -2 3 -4 3 -1 3 -5 1 -1输出 5 4 2 0 思路&#xff1a; 这里的题意就是&#xff0c; 当我们 i 取奇数的时候&#xff0c;可以获得该奇数 i 的值&#xff0c;并去掉当前卡牌。 当我们 i 取偶数的时候&#xff0c;去掉当…

钢轨长度及允许偏差

声明 本文是学习GB-T 2585-2021 铁路用热轧钢轨. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了铁路用钢轨的订货内容、分类、尺寸、外形、质量及允许偏差、技术要求、试验方法、检 验规则、标志及质量证明书。 本标准适用于3…

【斯坦福cs324w】中译版 大模型学习笔记九 大模型之Adaptation

文章目录 引言Adaptation的必要性从llm的训练过程分析从下游任务和原始训练任务之间的差异分析 通用的Adaptation配置 当前主流的Adaptation方法ProbingFine-tuningLightweight Fine-tuningPrompt TuningPrefix TuningAdapter Tuning 参考资料 在特定领域的下游任务中&#xff…