LeetCode 380. Insert Delete GetRandom O(1) 常数时间插入、删除和获取随机元素(C++/Java)
题目:
Design a data structure that supports all following operations in averageO(1) time.
insert(val): Inserts an item val to the set if not already present.remove(val): Removes an item val from the set if present.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)的更多相关文章
- [leetcode]380. Insert Delete GetRandom O(1)常数时间插入删除取随机值
Design a data structure that supports all following operations in average O(1) time. insert(val): In ...
- [LeetCode] 380. Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数
Design a data structure that supports all following operations in average O(1) time. insert(val): In ...
- [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 ...
- [LeetCode] Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数
Design a data structure that supports all following operations in average O(1) time. insert(val): In ...
- [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 ...
- LeetCode 380. Insert Delete GetRandom O(1)
380. Insert Delete GetRandom O(1) Add to List Description Submission Solutions Total Accepted: 21771 ...
- 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). ...
- LeetCode 380. Insert Delete GetRandom O(1) (插入删除和获得随机数 常数时间)
Design a data structure that supports all following operations in average O(1) time. insert(val): In ...
- [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 ...
随机推荐
- 自荐一个 element 表单代码生成器
Element UI 表单设计及代码生成器,可将生成的代码直接运行在基于 Element 的 vue 项目中. github仓库 https://github.com/JakHuang/form- ...
- Excel解除'工作表保护密码',并复原密码设定
前提要求 Office 2003(也就是老版的.xls文件) 用到宏操作 可以解除[审阅->保护工作表]的密码保护,其他的密码保护不能处理. 解决方案 打开需解除保护密码的Excel文件(.xl ...
- python实现上传文件到linux指定目录
今天接到一个小需求,就是想在windows环境下,上传压缩文件到linux指定的目录位置并且解压出来,然后我想了一下,这个可以用python试试写下. 环境:1.linux操作系统一台2.window ...
- 深度探索c++对象模型阅读笔记图
- Java锁对象和条件对象的使用
锁对象 临界区:临界区是一个特殊的代码段,该代码段访问某种特殊的公共资源,该资源同一时间只允许一个线程使用. Java中可以使用锁对象创造一个临界区: myLock.lock(); try { 关键代 ...
- Maven 生命周期的概念(指令默认顺序执行)
生命周期的概念 IDEA中使用maven构建项目都集中放到了窗口右侧"Maven Projects"中,点击该区域可以直观的看到,maven中几个常用指令都归类为LifeCycle ...
- POJ2186 Popular Cows 题解 强连通分量
题目链接:http://poj.org/problem?id=2186 题目大意: 每头牛都想成为牛群中的红人. 给定N头牛的牛群和M个有序对(A, B),(A, B)表示牛A认为牛B是红人: 该关系 ...
- schedule of 2016-10-17~2016-10-23(Monday~Sunday)——1st semester of 2nd Grade
most important things to do 1.joint phd preparations 2.journal paper to write 3.solid fundamental kn ...
- 3 分钟带你深入了解 Cookie、Session、Token
经常会有用户咨询,CDN 是否会传递 Cookie 信息,是否会对源站 Session 有影响,Token 的防盗链配置为什么总是配置失败?为此,我们就针对 Cookie.Session 和 Toke ...
- 【转】Java 正则表达式详解
正则表达式30分钟入门教程 常用正则表达式 如果你曾经用过Perl或任何其他内建正则表达式支持的语言,你一定知道用正则表达式处理文本和匹配模式是多么简单. 如果你不熟悉这个术语,那么“正则表达式”(R ...