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

实现RandomizedSet 类:

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

你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1)

之前没有写过类,现在写起来确实有点不太顺手,多练练就好啦!

我们要维护两个对象:

  • 随机访问(getRandom()):数组支持 O(1) 时间复杂度的随机访问(通过索引直接获取元素),而哈希表(Map)虽然可以快速查找元素是否存在,但无法直接随机访问元素。
  • 存储元素顺序:数组可以按插入顺序存储元素,而哈希表是无序的,无法直接支持随机访问。

插入逻辑:判断是否存在(map高效判断)+数组push+map.set

删除逻辑:将最后一个数覆盖要删除的数,然后删除最后一个数(数组pop),map(delete)

我的代码:

class RandomizedSet {// 第一次写集合还挺不习惯的// 不能在构造函数里面创造,要考虑作用域的问题private map: Map<number, number>; // 值到索引的映射private nums: number[]; // 存储所有值的数组constructor() {// 进行初始化this.map = new Map();this.nums = [];}insert(val: number): boolean {// 如果有数字就要插入到map末尾if(this.map.has(val)){// 已经存在返回falsereturn false;}else {// 长度刚好比索引多一个this.map.set( val , this.nums.length);this.nums.push(val);return true;}}remove(val: number): boolean {// 如果有的话就删除removeif(!this.map.has(val)){return false;}// 有值就要删除// 因为数组只有删除前面或者删除后面,我们想要达到O(1)就不能够遍历// 我们把要删除的数一道最后一个位置,直接pop// 得到index:const index = this.map.get(val);// 获取最后一个数let lastValue = this.nums[this.nums.length - 1];// 进行替换,同时要替换map的最后一个书的索引this.nums[index] = lastValue;this.map.set(lastValue  , index);// 删除最后一个数字this.nums.pop();this.map.delete(val);return true;}getRandom(): number {const randomIndex = Math.floor(Math.random() * this.nums.length);return this.nums[randomIndex];}
}/*** Your RandomizedSet object will be instantiated and called as such:* var obj = new RandomizedSet()* var param_1 = obj.insert(val)* var param_2 = obj.remove(val)* var param_3 = obj.getRandom()*/// O(1):哈希表
// 数组的一些方法:includes,pop

总结:

RandomizedSet 类通过结合哈希表和数组来实现。哈希表用于快速查找元素是否存在及其在数组中的索引,数组用于支持随机访问和高效地添加、删除元素。插入时,元素被添加到数组末尾,并在哈希表中记录其索引;删除时,通过交换待删除元素与数组末尾元素的方式,确保删除操作的时间复杂度为 O(1);获取随机元素时,通过生成随机索引直接从数组中获取。这种组合使得所有操作都能在平均 O(1) 时间内完成。

7.3 238. 除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

请 **不要使用除法,**且在 O(n) 时间复杂度内完成此题。

我最开始的思路:

当前的数的左边的数乘右边的数

我的代码:

function productExceptSelf(nums: number[]): number[] {// 当前的数let cur = 0;// 左边的指针let left = 0 ;// 右边的指针let right = 0 ; // 对每一个都要进行遍历// 最后的答案let ans = [] ;let subLeft = 1 ;let subRight = 1 ;  for(cur ; cur < nums.length ; cur++){left=0;right = nums.length - 1;subLeft = 1 ;subRight = 1;// `左边while(left < cur){subLeft = subLeft * nums[left];left++;}// 右边while(right > cur){subRight = subRight * nums[right];right--;}ans.push(subLeft * subRight);}return ans;
}

时间超限:双重循环(外层 for 循环 + 内层两个 while 循环),导致时间复杂度为 O(n²)

优化:也是左边成右边的,但是我们先左边乘积:从左到右遍历,ans[i] 初始化为左边所有元素的乘积。然后右边乘积:从右到左遍历,将 ans[i] 乘以右边所有元素的乘积。

优化后的代码:

function productExceptSelf(nums: number[]): number[] {// 对每一个都要进行遍历// 最后的答案let ans = [] ;let subLeft = 1 ;let subRight = 1 ; for(let i = 0 ;i < nums.length ; i++){ans[i] = subLeft;subLeft *= nums[i];}for(let i = nums.length - 1 ; i >= 0   ; i--){ans[i] *= subRight;subRight *= nums[i];}return ans;
}

总结:计算每一个nums[i]的左边,再和右边相乘得到结果

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

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

相关文章

需要scl来指定编译器的clangd+cmake在vscode/cursor开发环境下的配置

最近cursor更新了插件商店&#xff0c;只能使用默认它魔改的c/c插件&#xff08;基于clangd的&#xff09;&#xff0c;手头刚好在折腾一个cmake工程&#xff0c;试试水尝试直接配置在cursor上可以编译运行。 主要是本地环境使用scl来管理gcc/g&#xff0c;所以在配置过程中需要…

docker离线/在线环境下安装elasticsearch

如果想离线安装docker、redis、gninx、mysql可参照下面这个。 离线环境下&#xff0c;docker安装redis、ngnix、mysql 获取离线包 方式1 找一个能上网的环境&#xff0c;下载elasticsearch的镜像&#xff0c;然后将这个镜像导出 docker pull docker.elastic.co/elasticsear…

响应式编程入门教程第一节:揭秘 UniRx 核心 - ReactiveProperty - 让你的数据动起来!

响应式编程入门教程第一节&#xff1a;揭秘 UniRx 核心 - ReactiveProperty - 让你的数据动起来&#xff01;-CSDN博客 响应式编程入门教程第二节&#xff1a;构建 ObservableProperty&#xff1c;T&#xff1e; — 封装 ReactiveProperty 的高级用法-CSDN博客 今天我们来聊聊…

单片机:STM32F103的开发环境搭建

本文将详细介绍如何搭建STM32F103的开发环境。STM32F103是STMicroelectronics推出的一款基于ARM Cortex-M3内核的32位微控制器&#xff08;MCU&#xff09;&#xff0c;广泛应用于嵌入式开发。以下是搭建开发环境的详细步骤&#xff0c;涵盖硬件准备、软件安装、工具链配置及简…

eNSP中实现vlan间路由通信(路由器)

eNSP中实现vlan间路由通信&#xff08;路由器&#xff09; 拓扑图PC配置 pc1&#xff1a;192.168.10.1255.255.255.0192.168.10.254pc2&#xff1a;192.168.20.1255.255.255.0192.168.20.254pc3&#xff1a; 192.168.10.2255.255.255.0192.168.10.254pc4:192.168.20.2255.255.2…

spring6合集——spring概述以及OCP、DIP、IOC原则

spring6合集——Spring6核心知识点总结启示录一、SOLID原则1. 单一职责原则&#xff08;SRP&#xff09;2. 开闭原则&#xff08;OCP&#xff09;3. 里氏替换原则&#xff08;LSP&#xff09;4. 接口隔离原则&#xff08;ISP&#xff09;5. 依赖倒置原则&#xff08;DIP&#x…

Stata如何做机器学习?——SHAP解释框架下的足球运动员价值驱动因素识别:基于H2O集成学习模型

SHAP解释框架下的足球运动员价值驱动因素识别——基于H2O集成学习模型⚽ 欢迎关注 「阿水实证通」&#xff0c;前沿方法时刻看&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; 文章目录 SHAP解释框架下的足球运动员价值驱动因素识别——基于H2O集成学习模型⚽聚焦&…

基于Android的益智游戏学习系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业多年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

Oracle11G Linux版本(linux_x86_64_oracle11.2.0.4)

Oracle11G Linux版本 linux_x86_64_oracle11.2.0.4 文件分割成 七个 压缩包&#xff0c;必须集齐 七个 文件后才能一起解压一起使用&#xff1a; p13390677_112040_Linux-x86-64_7of7.zip下载地址&#xff1a; https://download.csdn.net/download/weixin_43800734/20303421 p1…

C++20中的counting_semaphore的应用

一、std::counting_semaphore 在前面介绍过C20中的同步库&#xff0c;其中就提到过std::counting_semaphore。但当时的重点是同步库的整体介绍&#xff0c;本文则会对std::counting_semaphore这个信号量进行一个全面的分析和说明&#xff0c;并有针对性的给出具体的例程。 C20中…

mongo常用命令

1 连接mongo服务器 mongo ip:端口/库名 -u 用户名 -p 密码 2 选择数据库 show dbs; 显示数据库列表 use 数据库名称; 3 集合操作 &#xff08;1&#xff09; 显示集合列表 show tables; &#xff08;2&#xff09;删除集合 db.集合名称.drop(); &#xff08;3&#x…

华为云 银河麒麟 vscode远程连接

解决方案 检查 SSH 服务器配置&#xff1a; 在远程主机上编辑 /etc/ssh/sshd_config 文件 关键配置说明&#xff1a; AllowTcpForwarding yes # 允许TCP端口转发&#xff08;必须开启&#xff09; AllowAgentForwarding yes # 允许SSH代理转发&#xff08;可选&#xf…

有限状态机(Finite State Machine)

文章目录有限状态机&#xff08;Finite State Machine&#xff09;简介状态机的组成六要素(1) 状态集合(2) 初态(3) 终态(4) 输入符号集(5) 输出符号集(6) 状态转移函数状态机的工作四要素(1) 现态(2) 输入(3) 输出(4) 次态FPGA中的状态机模型1. Moore型状态机(1) Moore l型(2)…

前端框架中注释占位与Fragment内容替换的实现与优化

在现代前端开发中&#xff0c;使用注释占位符替换Fragment内容是一种常见的需求&#xff0c;尤其在处理动态内容、模板预加载和组件复用场景中。React和Vue作为当前最主流的前端框架&#xff0c;提供了不同的实现方式和优化策略&#xff0c;但核心目标都是减少不必要的DOM操作&…

uniapp中使用web-worker性能优化的分享

为什么要使用 web-workers原因很简单&#xff0c;将复杂的计算逻辑和耗时逻辑放到线程中运行&#xff0c;避免ui阻塞&#xff0c;防止卡顿问题场景&#xff1a;本次运用于GPS 位置更新接入小程序注意事项&#xff1a;微信小程序中只允许存在一个 worker所以&#xff0c;需要再一…

5118 API智能处理采集数据教程

简数采集器支持调用5118 API接口处理采集的数据标题和内容、关键词、描述等&#xff0c;还可配合简数采集的SEO功能优化文章数据&#xff0c;对提高收录有积极的作用。 简数采集器支持5118接口&#xff1a;5118智能核心词提取API 和 5118智能摘要提取API 。 接入使用教程 1. …

【深度学习:进阶篇】--4.2.词嵌入和NLP

在RNN中词使用one_hot表示的问题 假设有10000个词 每个词的向量长度都为10000&#xff0c;整体大小太大 没能表示出词与词之间的关系 例如Apple与Orange会更近一些&#xff0c;Man与Woman会近一些&#xff0c;取任意两个向量计算内积都为0 目录 1.词嵌入 1.1.特点 1.3.wor…

WebRTC 的 ICE candidate 协商

文章目录 前言WebRTC 的 ICE candidate 协商1. 什么是 ICE candidate&#xff1f;2. ICE 协商的流程3.前端使用 ICE candidate 协商代码示例1&#xff09;收集 candidate 并发送2&#xff09;WebSocket 接收 candidate 并添加 4. ICE candidate 的类型5. ICE 协商常见问题6. 关…

卡尔曼滤波介绍

卡尔曼滤波介绍&#x1f4d6; **卡尔曼滤波原理简介**&#x1f511; **核心思想**&#x1f4e6; **卡尔曼滤波的组成**&#x1f50d; **代码分析&#xff08;kalman_filter.py&#xff09;**&#x1f3d7;️ 1. 状态空间定义&#x1f504; 2. 初始化模型矩阵&#x1f680; 3. 核…

递归与循环

文章目录递归TestRecursiveListRemoveNodeTestRecursiveListRemoveNode2循环TestWhileLoopListRemoveNodeTestWhileLoopListRemoveNode2递归 关键理解这几点&#xff1a; 1、求解基本问题 2、将原问题拆分为小问题&#xff0c;直至基本问题&#xff08;难点&#xff09; 3、借…