题目:

Design a data structure that supports all following operations in averageO(1) time.

  1. insert(val): Inserts an item val to the set if not already present.
  2. remove(val): Removes an item val from the set if present.
  3. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

Example:

// Init an empty set.
RandomizedSet randomSet = new RandomizedSet(); // Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomSet.insert(1); // Returns false as 2 does not exist in the set.
randomSet.remove(2); // Inserts 2 to the set, returns true. Set now contains [1,2].
randomSet.insert(2); // getRandom should return either 1 or 2 randomly.
randomSet.getRandom(); // Removes 1 from the set, returns true. Set now contains [2].
randomSet.remove(1); // 2 was already in the set, so return false.
randomSet.insert(2); // Since 2 is the only number in the set, getRandom always return 2.
randomSet.getRandom();

分析:

设计一个数据结构支持以下几个操作。

insert(val): 当元素 val 不存在时,向集合中插入该项。
remove(val): 元素 val 存在时,从集合中移除该项。
getRandom: 随机返回现有集合中的一项。每个元素应该有相同的概率被返回。

我们使用HashMap来支持插入和移除操作,利用数组来支持对数据的随机访问。插入元素时,将val和该val在数组中索引值存入map中,新插入的元素实际上在数组中的索引就是数组还有元素的个数,将元素加到动态数组的尾端。

移除元素时,为了能够达到O(1),除了将val在map中移除,还要对数组进行操作,如果单纯的将val所对应的索引处的元素删除,由于后续的所有元素都要向前移动,这样会浪费大量的时间。我们知道数组移除最后一个元素的时间复杂度时O(1),我们将要移除的元素和数组的最后一个元素交换,也可以将最后一个元素覆盖到要移除元素的位置,同时修改最后一个元素在map中对应的索引,最后删除掉数组最后一个元素,就可以保证常数时间的移除操作。最后在数组大小的范围内产生随机数,返回对应的元素,即可实现随机访问。

程序:

C++

class RandomizedSet {
public:
/** Initialize your data structure here. */
RandomizedSet() { } /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val) {
if(m.count(val))
return false;
m[val] = v.size();
v.push_back(val);
return true;
} /** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val) {
if(!m.count(val))
return false;
int index = m[val];
m[v.back()] = index;
v[index] = v.back();
m.erase(val);
v.pop_back();
return true;
} /** Get a random element from the set. */
int getRandom() {
int index = rand() % v.size();
return v[index];
}
private:
unordered_map<int, int> m;
vector<int> v;
};

Java

class RandomizedSet {

    /** Initialize your data structure here. */
public RandomizedSet() { } /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
public boolean insert(int val) {
if(map.containsKey(val))
return false;
map.put(val, list.size());
list.add(val);
return true;
} /** Removes a value from the set. Returns true if the set contained the specified element. */
public boolean remove(int val) {
if(!map.containsKey(val))
return false;
int index = map.get(val);
map.put(list.get(list.size()-1), index);
list.set(index, list.get(list.size()-1));
list.remove(list.size()-1);
map.remove(val);
return true;
} /** Get a random element from the set. */
public int getRandom() {
Random r = new Random();
return list.get(r.nextInt(list.size()));
}
private HashMap<Integer, Integer> map = new HashMap<>();
private ArrayList<Integer> list = new ArrayList<>();
}

LeetCode 380. Insert Delete GetRandom O(1) 常数时间插入、删除和获取随机元素(C++/Java)的更多相关文章

  1. [leetcode]380. Insert Delete GetRandom O(1)常数时间插入删除取随机值

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  2. [LeetCode] 380. Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  3. [LeetCode] 381. Insert Delete GetRandom O(1) - Duplicates allowed 插入删除和获得随机数O(1)时间 - 允许重复

    Design a data structure that supports all following operations in average O(1) time. Note: Duplicate ...

  4. [LeetCode] Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  5. [LeetCode] 380. Insert Delete GetRandom O(1) 插入删除获得随机数O(1)时间

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  6. LeetCode 380. Insert Delete GetRandom O(1)

    380. Insert Delete GetRandom O(1) Add to List Description Submission Solutions Total Accepted: 21771 ...

  7. leetcode 380. Insert Delete GetRandom O(1) 、381. Insert Delete GetRandom O(1) - Duplicates allowed

    380. Insert Delete GetRandom O(1) 实现插入.删除.获得随机数功能,且时间复杂度都在O(1).实际上在插入.删除两个功能中都包含了查找功能,当然查找也必须是O(1). ...

  8. LeetCode 380. Insert Delete GetRandom O(1) (插入删除和获得随机数 常数时间)

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  9. [leetcode]380. Insert Delete GetRandom O(1)设计数据结构,实现存,删,随机取的时间复杂度为O(1)

    题目: Design a data structure that supports all following operations in average O(1) time.1.insert(val ...

随机推荐

  1. 不仅仅是双11大屏—Flink应用场景介绍

    双11大屏 每年天猫双十一购物节,都会有一块巨大的实时作战大屏,展现当前的销售情况. 这种炫酷的页面背后,其实有着非常强大的技术支撑,而这种场景其实就是实时报表分析. 实时报表分析是近年来很多公司采用 ...

  2. 【题解】CF986E Prince's Problem(树上差分+数论性质)

    [题解]CF986E Prince's Problem(树上差分+数论性质) 题目大意: 给定你一棵树,有点权\(val_i\le 10^7\).现在有\(m\)组询问给定参数\(x,y,w\)问你对 ...

  3. $CH$3801 $Rainbow$的信号 期望+位运算

    正解:位运算 解题报告: 传送门! 其实就是个位运算,,,只是顺便加了个期望的知识点$so$期望的帕并不难来着$QwQ$ 先把期望的皮扒了,就直接分类讨论下,不难发现,答案分为两个部分 $\left\ ...

  4. Scala:用于Java的轻量级函数式编程

    Scala为Java开发提供了轻量级的代码选项,但是学习过程可能会很艰难.了解有关Scala的知识以及是否值得采用. 基于Java的语言通常涉及冗长的语法和特定于领域的语言,用于测试,解析和数值计算过 ...

  5. SpringCloudAlibaba通过jib插件打包发布到docker仓库

    序言 在SpringBoot项目部署的时候,我了解到了Jib插件的强大,这个插件可以快速构建镜像发布到我们的镜像仓库当中去.于是我打算在毕设当中加上这个功能,并且整合到github actions中去 ...

  6. docker+mysql 构建数据库的主从复制

    docker+mysql 构建数据库的主从复制 在最近的项目中,决定将项目改造成数据库读写分离的架构,后续会有博文详细讲述我的开发改造,本文主要记录我是如何一步步的构建数据库的主从复制. 为什么使用d ...

  7. Go 开发关键技术指南 | 敢问路在何方?(内含超全知识大图)

    作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 Go 开发关键技术指南文章目录: 为什么你要选择 Go? Go 面向失败编程 带着服务器编程金刚经走进 2020 年 敢问路在何方? Go 开发指南大图 ...

  8. Java扫描指定文件路径下的文件并且递归扫描其子目录下的所有文件

    本文主要实现了扫描指定文件路径下的文件,递归扫描其子目录下的所有文件信息,示例文件为: 要求将后缀为.dat的文件夹信息也写入到数据库中,然后将.chk文件解析,将文件中对应的内容读出来写入到数据库, ...

  9. js如何下载后台传过来的base64文件

    一.<a>标签的作用 相信大部分人都知道<a>链接再简单不过了,跳转嘛,跳转到另外一个页面,这谁不知道. 当然这这是一部分, <a> 标签定义超链接,用于从一个页面 ...

  10. MongoDB Community 的安装和卸载

    MongoDB在他们的仓库中提供官方支持的包,该仓库包括以下软件包 mongodb-org:自动安装下面的四个组件安装包 a.mongodb-org-server:mongod的守护进程和相关的配置以 ...