You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/** * Initialize your data structure here. */varRandomizedCollection=function(){this.list=[]this.map={}};/** * Inserts a value to the collection. Returns true if the collection did not already contain the specified element. * @param {number} val * @return {boolean} */RandomizedCollection.prototype.insert=function(val){this.list.push(val)if(!this.map[val]||this.map[val].length==0){// val 在map中的下标集合,相同的val可能有多个,所以用数组来存储下标值this.map[val]=[this.list.length-1]returntrue}else{this.map[val].unshift(this.list.length-1)returnfalse}};/** * Removes a value from the collection. Returns true if the collection contained the specified element. * @param {number} val * @return {boolean} */RandomizedCollection.prototype.remove=function(val){if(!this.map[val]||this.map[val].length==0)returnfalseconstindex=this.map[val].shift()constfinal=this.list[this.list.length-1]if(final!==val){this.list[index]=finalthis.map[final][0]=indexthis.map[final].sort((a,b)=>b-a)}this.list.pop()returntrue};/** * Get a random element from the collection. * @return {number} */RandomizedCollection.prototype.getRandom=function(){constindex=Math.floor(Math.random()*this.list.length)returnthis.list[index]};
/** * Initialize your data structure here. */varRandomizedSet=function(){this.list=[];this.map={};};/** * Inserts a value to the set. Returns true if the set did not already contain the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.insert=function(val){if(!this.map[val]){this.list.push(val)this.map[val]=this.list.lengthreturntrue}else{returnfalse}};/** * Removes a value from the set. Returns true if the set contained the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.remove=function(val){if(this.map[val]){this.list=this.list.filter(item=>item!=val)deletethis.map[val]returntrue}else{returnfalse}};/** * Get a random element from the set. * @return {number} */RandomizedSet.prototype.getRandom=function(){functionrandomFrom(lowerValue,upperValue){returnMath.floor(Math.random()*(upperValue-lowerValue)+lowerValue);}returnthis.list[randomFrom(0,this.list.length)]};/** * Your RandomizedSet object will be instantiated and called as such: * var obj = new RandomizedSet() * var param_1 = obj.insert(val) * var param_2 = obj.remove(val) * var param_3 = obj.getRandom() */
/** * Initialize your data structure here. */varRandomizedSet=function(){//表示数组中的对应的值的下标是多少//然后删除的时候就可以根据val找到数组里面的下标 然后在数组中进行删除this.map=newMap();//存放值this.values=[];};/** * Inserts a value to the set. Returns true if the set did not already contain the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.insert=function(val){//如果已经有这个值了就返回falseif(this.map.has(val)){returnfalse;}else{//在表中记录插入的值在数组中的下标this.map.set(val,this.values.length);//在数组中添加这个值this.values.push(val);returntrue;}};/** * Removes a value from the set. Returns true if the set contained the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.remove=function(val){if(this.map.has(val)){// 找到要删除的值的下标constdeleteIndex=this.map.get(val);// 得到最后一个元素constlastVal=this.values.pop();// 用最后一个数代替要删除的值this.values[deleteIndex]=lastVal;// 更新本来是最后一个元素在map中记录的下标this.map.set(lastVal,deleteIndex);// 在map中删除this.map.delete(val);returntrue;}else{//如果没有这个值就返回falsereturnfalse;}};/** * Get a random element from the set. * @return {number} */RandomizedSet.prototype.getRandom=function(){letsize=this.values.length;//返回一个0到values的长度之间的随机数letrandom=Math.floor(Math.random()*size);//以随机数为下标返回returnthis.values[random];};
letRandomizedSet=function(){this.list=[]this.map={}};RandomizedSet.prototype.insert=function(val){this.list.push(val)if(!this.map[val]||this.map[val].length==0){// val 在map中的下标集合,相同的val可能有多个,所以用数组来存储下标值this.map[val]=[this.list.length-1]returntrue}else{this.map[val].unshift(this.list.length-1)returnfalse}};RandomizedSet.prototype.remove=function(val){if(!this.map[val]||this.map[val].length==0)returnfalseconstindex=this.map[val].shift()constfinal=this.list[this.list.length-1]if(final!==val){this.list[index]=finalthis.map[final][0]=indexthis.map[final].sort((a,b)=>b-a)}this.list.pop()returntrue};RandomizedSet.prototype.getRandom=function(){constindex=Math.floor(Math.random()*this.list.length)returnthis.list[index]};
letRandomizedSet=function(){this.list=[]this.map={}};RandomizedSet.prototype.insert=function(val){this.list.push(val)if(!this.map[val]||this.map[val].length==0){// val 在map中的下标集合,相同的val可能有多个,所以用数组来存储下标值this.map[val]=[this.list.length-1]returntrue}else{this.map[val].unshift(this.list.length-1)returnfalse}};RandomizedSet.prototype.remove=function(val){if(!this.map[val]||this.map[val].length==0)returnfalseconstindex=this.map[val].shift()constfinal=this.list[this.list.length-1]if(final!==val){this.list[index]=finalthis.map[final][0]=indexthis.map[final].sort((a,b)=>b-a)}this.list.pop()returntrue};RandomizedSet.prototype.getRandom=function(){constindex=Math.floor(Math.random()*this.list.length)returnthis.list[index]};
varRandomizedSet=function(){this.hashMap=newMap();this.arr=[];}/** * Inserts a value to the set. Returns true if the set did not already contain the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.insert=function(val){if(this.hashMap.has(val)){returnfalse}else{this.hashMap.set(val,this.arr.length);this.arr.push(val);returntrue}};/** * Removes a value from the set. Returns true if the set contained the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.remove=function(val){vardelIndex=this.hashMap.get(val);if(delIndex===undefined){returnfalse;}else{varlastNum=this.arr[this.arr.length-1];this.arr[delIndex]=lastNum;this.hashMap.set(lastNum,delIndex);this.arr.pop();returnthis.hashMap.delete(val);}};/** * Get a random element from the set. * @return {number} */RandomizedSet.prototype.getRandom=function(){varrandom=Math.floor(Math.random()*this.arr.length);returnthis.arr[random];};
/** * Initialize your data structure here. */varRandomizedSet=function(){this.hash={};this.arr=[];};/** * Inserts a value to the set. Returns true if the set did not already contain the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.insert=function(val){// 如果存在返回falseif(this.hash[val]!==undefined){returnfalse;}else{// 如果不存在hash表中,将其加入arr中,并数之hash以val为键的值为当前indexthis.arr.push(val);this.hash[val]=this.arr.length-1;// 其实就是当前值在数组中的indexreturntrue;}};/** * Removes a value from the set. Returns true if the set contained the specified element. * @param {number} val * @return {boolean} */RandomizedSet.prototype.remove=function(val){// 存在才删除if(this.hash[val]!==undefined){// 交换当前值与数组末尾元素[this.arr[this.hash[val]],this.arr[this.arr.length-1]]=[this.arr[this.arr.length-1],this.arr[this.hash[val]]];// 更改末尾元素的indexthis.hash[this.arr[this.hash[val]]]=this.hash[val];// 清除末尾元素this.arr.pop();// 删除hash表中的值deletethis.hash[val];returntrue;}else{returnfalse;}};/** * Get a random element from the set. * @return {number} */RandomizedSet.prototype.getRandom=function(){returnthis.arr[Math.random()*(this.arr.length)|0];};/** * Your RandomizedSet object will be instantiated and called as such: * var obj = new RandomizedSet() * var param_1 = obj.insert(val) * var param_2 = obj.remove(val) * var param_3 = obj.getRandom() */
fromrandomimportrandomclassRandomizedSet:
def__init__(self):
""" Initialize your data structure here. """self.data=dict()
self.arr= []
self.n=0definsert(self, val: int) ->bool:
""" Inserts a value to the set. Returns true if the set did not already contain the specified element. """ifvalinself.data:
returnFalseself.data[val] =self.nself.arr.append(val)
self.n+=1returnTruedefremove(self, val: int) ->bool:
""" Removes a value from the set. Returns true if the set contained the specified element. """ifvalnotinself.data:
returnFalsei=self.data[val]
# 更新dataself.data[self.arr[-1]] =iself.data.pop(val)
# 更新arrself.arr[i] =self.arr[-1]
# 删除最后一项self.arr.pop()
self.n-=1returnTruedefgetRandom(self) ->int:
""" Get a random element from the set. """returnself.arr[int(random() *self.n)]
# Your RandomizedSet object will be instantiated and called as such:# obj = RandomizedSet()# param_1 = obj.insert(val)# param_2 = obj.remove(val)# param_3 = obj.getRandom()
Activity
plane-hjh commentedon May 25, 2020
Loading-m commentedon May 25, 2020
这个getRandom不是要概率相等吗 这个概率为什么是相等的
7777sea commentedon May 25, 2020
luweiCN commentedon May 25, 2020
自己没想出来,看了题解的提示想到用Map和数组结合的方式。不得不说remove的操作因为惯性思维不太容易想到
luweiCN commentedon May 25, 2020
insert有问题吧,insert 的时候如果有已经存在,按照题目要求返回false,为什么要用数组把它们下标都存下来
plane-hjh commentedon May 25, 2020
不好意思,没看清,已改,谢谢指出 @luweiCN
sisterAn commentedon May 25, 2020
解答一:Map+数组
解答二:也可以使用Set
leetcode
13001920223 commentedon May 26, 2020
guanping1210 commentedon May 26, 2020
AnranS commentedon Nov 14, 2020
azl397985856 commentedon Mar 3, 2021
题目地址(380. 常数时间插入、删除和获取随机元素)
https://leetcode-cn.com/problems/insert-delete-getrandom-o1/description/
题目描述
思路
这是一个设计题。这道题的核心就是考察基本数据结构和算法的操作以及复杂度。
我们来回顾一下基础知识:
由于题目要求 getRandom 返回要随机并且要在$O(1)$复杂度内,那么如果单纯使用链表或者哈希表肯定是不行的。
而又由于对于插入和删除也需要复杂度为$O(1)$,因此单纯使用数组也是不行的,因此考虑多种使用数据结构来实现。
对于 getRandom 用数组很简单。对于判断是否已经有了存在的元素,我们使用哈希表也很容易做到。因此我们可以将数组随机访问,以及哈希表$O(1)$按检索值的特性结合起来,即同时使用这两种数据结构。
对于删除和插入,我们需要一些技巧。
对于插入:
因此如何应付删除的这种性能开销呢? 我们知道对于数据删除,我们的时间复杂度来源于
查找到要删除的元素重新排列被删除元素后面的元素。对于 1,我们可以通过哈希表来实现。 key 是插入的数字,value 是数组对应的索引。删除的时候我们根据 key 反查出索引就可以快速找到。
对于 2,我们可以通过和数组最后一项进行交换的方式来实现,这样就避免了数据移动。同时数组其他项的索引仍然保持不变,非常好!
图解:
以依次【1,2,3,4】之后为初始状态,那么此时状态是这样的:
而当要插入一个新的 5 的时候, 我们只需要分别向数组末尾和哈希表中插入这条记录即可。
而删除的时候稍微有一点复杂:
关键点解析
代码
复杂度分析
更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。
大家也可以关注我的公众号《力扣加加》获取更多更新鲜的 LeetCode 题解
JohnApache commentedon Apr 30, 2021
为什么都用
list+map,list存储数据方便,但是删除数据就不算很优雅了啊,我直接用了 两个map实现这个效果