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

[M模拟] lc380. O(1) 时间插入、删除和获取随机元素(模拟+数据结构+脑筋急转弯+数组快捷删除技巧+项目思考)

文章目录

    • 1. 题目来源
    • 2. 题目解析

1. 题目来源

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

题单:

  • 待补充

2. 题目解析

其实这个题目抽象一下的话在项目中也能出现,可能日常项目中没有算法基础的话,就很容易直接去进行新内存开辟、重复遍历等操作。尤其是在哈希表删除后,又需要进行一个相同概率返回的这个操作的时候。常见就有重新遍历哈希表到临时数组对象中,然后再依靠 rand 函数进行返回。

那么 O ( n ) O(n) O(n) 次的查询情况下每一个遍历都是 O ( n ) O(n) O(n) 的,那么整体的时间复杂度就是妥妥的 O ( n 2 ) O(n^2) O(n2) 的,在高并发场景下,这就是妥妥的项目坑点啊。

思路:

  • 构建一个哈希表、一个数组。哈希表用来存放 val 及数组中的该 val 的下标。数组用来存放全部元素, 便于最后通过 rand 函数进行相同概率的直接返回,避免遍历哈希表。
  • 主要是删除元素的时候,哈希表元素与数组元素怎么快速做到 O ( 1 ) O(1) O(1) 删除。
    • 我们只需要将数组最后一个元素与待删除元素调换位置,然后将最后一个元素 pop 出去就可以做到 O ( 1 ) O(1) O(1) 的删除了。
    • 同样上述的思想,在堆排序的向上调整、向下调整中也有用到。
    • 在如何 O ( 1 ) O(1) O(1) 删除单链表中的某一个节点元素的时候也有用到。

具体的看下如下代码即可,代码好理解,但如何运用到项目中去显著提高业务响应速度是值得我们去深思斟酌的。


  • 时间复杂度 O ( 1 ) O(1) O(1)
  • 空间复杂度 O ( n ) O(n) O(n)

type RandomizedSet struct {m map[int]int  // val--idx   存 val 值,及在 s 中的下标位置s []int        // val        存 val 值
}func Constructor() RandomizedSet {r := RandomizedSet {s: make([]int, 0, 32),m: make(map[int]int),}return r
}func (r *RandomizedSet) Insert(val int) bool {if _, ok := r.m[val]; ok {return false}r.m[val] = len(r.s)       // 新插入的 val 元素在 s 中的下标为总长度,及尾插r.s = append(r.s, val)return true
}func (r *RandomizedSet) Remove(val int) bool {id, ok := r.m[val]if !ok {return false}last := len(r.m) - 1  // 拿到最后一个元素的下标r.s[id] = r.s[last]   // 在数组中,用最后一个元素值覆盖掉要删除的元素值,方便等会直接删除最后一个元素就行r.m[r.s[last]] = id   // 在哈希表中,重新建立索引关系,最后一个元素的哈希值应该是待删除元素的数组中的下标位置r.s = r.s[:last]      // 切片操作,删除最后一个元素即可delete(r.m, val)      // 哈希表操作,删除哈希表元素即可return true
}func (r *RandomizedSet) GetRandom() int {return r.s[rand.Intn(len(r.s))]  // 随机化操作
}/*** Your RandomizedSet object will be instantiated and called as such:* obj := Constructor();* param_1 := obj.Insert(val);* param_2 := obj.Remove(val);* param_3 := obj.GetRandom();*/

http://www.mrgr.cn/news/90031.html

相关文章:

  • 企业如何利用DeepSeek提升网络安全管理水平
  • Intellij IDEA如何查看当前文件的类
  • Ranger Admin安装MySQL初始化问题解决
  • 【Rust自学】20.4. 结语:Rust学习一阶段完成+附录
  • 【JVM详解四】执行引擎
  • BUU28 [GXYCTF2019]BabySQli1
  • Maven入门核心知识点总结
  • 【Matlab优化算法-第14期】基于智能优化算法的VMD信号去噪项目实践
  • Java虚拟机面试题:类加载机制
  • 深入理解Java三大特性:封装、继承和多态
  • 【STM32基础】STM32F4 USB通信之HID设备(基于CubeMX)
  • 51单片机俄罗斯方块计分函数
  • 位图的深入解析:从数据结构到图像处理与C++实现
  • 蚂蚁爬行最短问题
  • 【蓝桥杯嵌入式】UART(收发)
  • 计算机毕业设计Python+Vue.js游戏推荐系统 Steam游戏推荐系统 Django Flask 游 戏可视化 游戏数据分析 游戏大数据 爬虫
  • Centos Stream 10 根目录下的文件夹结构
  • 【HeadFirst系列之HeadFirstJava】第2天之类与对象-拜访对象村
  • OpenGL学习笔记(十二):初级光照:投光物/多光源(平行光、点光源、聚光)
  • Shapefile格式文件解析和显示
  • Office/WPS接入DeepSeek等多个AI工具,开启办公新模式!
  • 《Wiki.js知识库部署实践 + CNB Git数据同步方案解析》
  • 【算法】动态规划专题⑨ —— 二维费用背包问题 python
  • springboot简单应用
  • 【SQL教程|05】Mysql中Limit用法详解
  • 大疆前端开发面试题及参考答案(4万字长文)