Design a data structure that supports all following operations in average O(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 1 is the only number in the set, getRandom always return 1.
randomSet.getRandom();

设计一个数据结构在O(1)时间内完成:insert(val),remove(val),getRandom()

由于是O(1)时间,要用哈希表 + 数组(HashMap + Array),数组用来保存数字,哈希表用来建立每个数字和其在数组中的位置之间的映射。

插入操作:先判断是否在HashMap里,如果存在则不需要插入,直接返回false。不存在的话,把此数插入到数组的末尾,然后在HashMap中建立数字和其位置的映射。

删除操作:先判断是否在HashMap里,如果没有,直接返回false。由于HashMap的删除是O(1)时间,而数组并不是。为了保证了O(1)时间内的删除,把要删除的数字和数组的最后一个数调换个位置,然后修改对应的HashMap中的值,删除数组的最后一个元素即可。

返回随机数:随机生成一个数组位置,返回该位置上的数字。

Java:

public class RandomizedSet {
Map<Integer, Integer> map;//<val, index in arrlist>
List<Integer> list;//keep a record of value for get random
int size;//map and list are the same size
Random rand;
/** Initialize your data structure here. */
public RandomizedSet() {
this.map = new HashMap<>();
this.list = new ArrayList<>();
this.size = 0;
this.rand = new Random();
} /** 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, size);
list.add(val);
size++;
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)){
int last = list.get(size - 1);
list.set(map.get(val), last);//use last added ele to fill the element to be removed
map.put(last, map.get(val));//update last added ele's index in list
map.remove(val);
list.remove(size - 1);//remove at end is constant
size--;
return true;
}
return false;
} /** Get a random element from the set. */
public int getRandom() {
return list.get(rand.nextInt(size));
}
}

Python:

import random
class RandomizedSet(object): def __init__(self):
"""
Initialize your data structure here.
"""
self.dataMap = {}
self.dataList = [] def insert(self, val):
"""
Inserts a value to the set. Returns true if the set did not already contain the specified element.
:type val: int
:rtype: bool
"""
if val in self.dataMap:
return False
self.dataMap[val] = len(self.dataList)
self.dataList.append(val)
return True def remove(self, val):
"""
Removes a value from the set. Returns true if the set contained the specified element.
:type val: int
:rtype: bool
"""
if val not in self.dataMap:
return False
idx = self.dataMap[val]
tail = self.dataList.pop()
if idx < len(self.dataList):
self.dataList[idx] = tail
self.dataMap[tail] = idx
del self.dataMap[val]
return True def getRandom(self):
"""
Get a random element from the set.
:rtype: int
"""
return random.choice(self.dataList)  

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;
nums.push_back(val);
m[val] = nums.size() - 1;
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 last = nums.back();
m[last] = m[val];
nums[m[val]] = last;
nums.pop_back();
m.erase(val);
return true;
} /** Get a random element from the set. */
int getRandom() {
return nums[rand() % nums.size()];
}
private:
vector<int> nums;
unordered_map<int, int> m;
};

类似题目:

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

All LeetCode Questions List 题目汇总

[LeetCode] 380. Insert Delete GetRandom O(1) 插入删除获得随机数O(1)时间的更多相关文章

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

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

  2. 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). ...

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

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

  4. LeetCode 380. 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)常数时间插入删除取随机值

    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) 常数时间插入、删除和获取随机元素(C++/Java)

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

  7. [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 ...

  8. [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 ...

  9. LeetCode 381. Insert Delete GetRandom O(1) - Duplicates allowed O(1) 时间插入、删除和获取随机元素 - 允许重复(C++/Java)

    题目: Design a data structure that supports all following operations in averageO(1) time. Note: Duplic ...

随机推荐

  1. django项目使用layui插件给网站设置一个日历挂件,很简单实用。

    进入https://www.layui.com/首页下载layui文件 下载解压后把文件放在static静态文件中, html页面引入css和js <link rel="stylesh ...

  2. metasploit 一款开源的渗透测试框架

    渗透神器漏洞利用框架metasploit from: https://zhuanlan.zhihu.com/p/30743401 metasploit是一款开源的渗透测试框架软件也是一个逐步发展与成熟 ...

  3. R笔记整理(持续更新中)

    1. 安装R包 install.packages("ggplot2") #注意留意在包的名称外有引号!!! library(ggplot2) #在加载包的时候,则不需要在包的名称外 ...

  4. PHP——file_put_contents()函数

    前言 作为PHP的一个内置函数,他的作用就是将一个字符串写入文件 简介 使用 换行和追加写入 file_put_contents('./relation/bind.txt', $val['id'].' ...

  5. centos7中,mysql连接报错:1130 - Host ‘118.111.111.111’ is not allowed to connect to this MariaDB server

    客户端连接报错 这个问题是因为用户在数据库服务器中的mysql数据库中的user的表中没有权限. 解决步骤 1.连接服务器: mysql -u root -p 2.看当前所有数据库:show data ...

  6. Linux配置静态IP以及解决配置静态IP后无法上网的问题

    式一.图形界面配置

  7. 目标检测中的bounding box regression

    目标检测中的bounding box regression 理解:与传统算法的最大不同就是并不是去滑窗检测,而是生成了一些候选区域与GT做回归.

  8. 讨论SQL语句中主副表之间的关系

    在公司这么多些时间,自己在写SQL语句这方面的功夫实在是太差劲了,有时候自己写出来的SQL语句自己都不知道能不能使用,只是自己写出来的SQL语句是不报错的,但是,这对于真正意义上的SQL语句还差的真的 ...

  9. Centos7安装Hive2.3

    准备 1.hadoop已部署(若没有可以参考:Centos7安装Hadoop2.7),集群情况如下: hostname IP地址 部署规划 node1 172.20.0.4 NameNode.Data ...

  10. 六.深浅copy

    先问问大家,什么是拷贝?拷贝是音译的词,其实他是从copy这个英文单词音译过来的,那什么是copy? copy其实就是复制一份,也就是所谓的抄一份.深浅copy其实就是完全复制一份,和部分复制一份的意 ...