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

面试算法30:插入、删除和随机访问都是O(1)的容器

题目

设计一个数据结构,使如下3个操作的时间复杂度都是O(1)。

  • insert(value):如果数据集中不包含一个数值,则把它添加到数据集中。
  • remove(value):如果数据集中包含一个数值,则把它删除。
  • getRandom():随机返回数据集中的一个数值,要求数据集中每个数字被返回的概率都相同。

分析

由于题目要求插入和删除(包括判断数据集中是否包含一个数值)的时间复杂度都是O(1),能够同时满足这些时间效率要求的只有哈希表,因此这个数据结构要用到哈希表。但是如果只用哈希表,则不能等概率地返回其中的每个数值。

如果数值是保存在数组中的,那么很容易实现等概率返回数组中的每个数值。假设数组的长度是n,那么等概率随机生成从0到n-1的一个数字。如果生成的随机数是i,则返回数组中下标为i的数值。由此可以发现,需要结合哈希表和数组的特性来设计这个数据容器。

由于数值保存在数组中,因此需要知道每个数值在数组中的位置,否则在删除的时候就必须顺序扫描整个数组才能找到待删除的数值,那就需要O(n)的时间。通常把每个数值在数组中的位置信息保存到一个HashMap中,HashMap的键是数值,而对应的值为它在数组中的位置。

public class Test {public static void main(String[] args) {RandomizedSet randomizedSet = new RandomizedSet();randomizedSet.insert(1);randomizedSet.insert(2);randomizedSet.insert(3);randomizedSet.insert(4);for (int i = 0; i < randomizedSet.nums.size(); i++) {System.out.println(randomizedSet.nums.get(i));}System.out.println("-----------------------");randomizedSet.remove(2);for (int i = 0; i < randomizedSet.nums.size(); i++) {System.out.println(randomizedSet.nums.get(i));}System.out.println("-----------------------");System.out.println(randomizedSet.getRandom());}static class RandomizedSet {HashMap<Integer, Integer> numToLocation;ArrayList<Integer> nums;public RandomizedSet() {numToLocation = new HashMap<>();nums = new ArrayList<>();}public boolean insert(int val) {if (numToLocation.containsKey(val)) {return false;}numToLocation.put(val, nums.size());nums.add(val);return true;}public boolean remove(int val) {if (!numToLocation.containsKey(val)) {return false;}int location = numToLocation.get(val);numToLocation.put(nums.get(nums.size() - 1), location);numToLocation.remove(val);nums.set(location, nums.get(nums.size() - 1));nums.remove(nums.size() - 1);return true;}public int getRandom() {Random random = new Random();int r = random.nextInt(nums.size());return nums.get(r);}}
}
http://www.lryc.cn/news/199172.html

相关文章:

  • Qt/C++开源作品45-CPU内存显示控件/和任务管理器一致
  • win32汇编-使用子程序
  • 【论文阅读】 Cola-Dif; An explainable task-specific synthesis network
  • ShareMouse for Mac(多台电脑鼠标键盘共享软件)
  • 中文编程开发语言工具开发案例:多种称重方式编程实际例子
  • 国密sm2的Vue、Python、Java互通使用
  • 如何通过SK集成chatGPT实现DotNet项目工程化?
  • DRM中render-node编号的分配
  • 将输入对象转换为数组数组的维度大于等于1numpy.atleast_1d()
  • js 删除树状图无用数据,如果子级没有数据则删除
  • Docker 容器化(初学者的分享)
  • LCS 01.下载插件
  • 架构-设计原则
  • 在 Python 3 中释放 LightGBM 的力量:您的机器学习大师之路
  • Spring学习笔记(2)
  • cmd使用ssh连接Linux脚本
  • Python万圣节蝙蝠
  • TCP流套接字编程
  • Python迭代器创建与使用:从入门到精通
  • mac虚拟机安装homebrew时的问题
  • 学信息系统项目管理师第4版系列32_信息技术发展
  • Vue3 + Nodejs 实战 ,文件上传项目--大文件分片上传+断点续传
  • 宏(预编译)详解
  • hue实现对hiveserver2 的负载均衡
  • SkyWalking 告警规则配置说明
  • HTML 表单笔记/练习
  • 关于Java Integer和Long使用equals直接比较
  • nodejs+vue衣服穿搭推荐系统-计算机毕业设计
  • Java并发面试题:(七)ThreadLocal原理和内存泄漏
  • 香港服务器在国内访问太慢怎么能提高?