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 ...
随机推荐
- 【题解】P1373 小a和uim之大逃离
[题解]P1373 小a和uim之大逃离 考虑到可能会MLE,考虑状态压缩一下 由于只要得到他们的差就行了,所以直接少记录一维就好了 \(dp(i,j,r,1/0)\)表示在\(i,j\)点,当前ui ...
- Python用PIL将PNG图像合成gif时如果背景为透明时图像出现重影的解决办法
最近在用PIL合成PNG图像为GIF时,因为需要透明背景,所以就用putpixel的方法替换背景为透明,但是在合成GIF时,图像出现了重影,在网上查找了GIF的相关资料:GIF相关资料 其中有对GIF ...
- DispatcherServlet的url-pattern尽量不要配置为"/*"
DispatcherServlet的url-pattern尽量不要配置为"/*" 原因 当Dispatcher的url配置为"/*"时,会把tomcat的web ...
- 前端Tips#3 - 简写的 border-radius 100% 和 50% 是等效的
本文同步自 JSCON简时空 - 技术博客,点击阅读 视频讲解 视频地址 文字讲解 1.先讲结论 border-radius 这个 css 属性大家应该使用得非常娴熟,现实中用到的场景基本都是四个圆角 ...
- Android系统启动过程分析
Android系统启动过程分析 一.Android平台架构 首先贴一张Android系统架构图方便理解整个Android架构,这可以让我们从整体上对整个启动流程有个大概认知. 可以看出整个架构由5部分 ...
- Vmware下Ubuntu 14.04静态IP地址的设置方法
一.环境 宿主机 Win 8.1 虚拟机工具 VMware 10.0 虚拟主机系统 Ubuntu 14.04 二.说明 这里需要注意的是:VMware对于VMnet8采用如下规则(192.168. ...
- No property andp found for type String! Traversed path: CmsPage.siteId.
Respository没有找到该参数 1)由该参数,函数名写错,不符合JPA规范 2)实体类没有该参数
- Task 线程重用导致等待!
测试代码: ; i < ; i++) { var d = DateTime.Now; Task.Run(() => { Console.WriteLine($"{Thread.C ...
- js六种数据类型
六种数据类型: undefined . boolean .string .number .object .function 效果地址:https://scrimba.com/c/cEedDGTd 代 ...
- SpringMVC启动流程源码解密
我们知道,SpringMVC最后是通过Tomcat来进行部署的.当在Servlet中进行进行应用部署时,主要步骤为(引用来自http://download.oracle.com/otn-pub/jcp ...