基础知识
1.集合和字典
创建空集合:A=set()
创建空字典:L={ }
上图中a为字典,字典的键为一个元素值,键值为一个集合
2.pop()
(1)list.pop([index=-1])
移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
(2)set.pop()
随机移除元素,set 集合的 pop 方法会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。
3.choice()
题目:
设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。注意: 允许出现重复元素。
insert(val):向集合中插入元素 val。
remove(val):当 val 存在时,从集合中移除一个 val。(注意:此处只需删除一个即可)
getRandom:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
思路:
借助列表和字典
列表用来记录当前的所有已插入的元素值
字典用来记录:列表中存在的元素值(键),及元素值在列表中所出现的索引位置(键值,为一个集合)
解答:
class RandomizedCollection:
def __init__(self):
"""
Initialize your data structure here.
"""
#创建一个列表和字典,其中字典的键为待插入的值,键值为一个集合
self.list1=[]
self.dict1={}
def insert(self, val: int) -> bool:
"""
Inserts a value to the collection. Returns true if the collection did not already contain the specified element.
"""
#返回当前列表的长度
slen=len(self.list1)
#返回字典中键val对应的键值,为一个集合
vset=self.dict1.get(val)
self.list1.append(val)
if vset:
#若键val在字典中已存在,记录元素在列表中的位置,键为val,键值为一个集合,代表val在列表中出现的位置
self.dict1[val].add(slen)
return False
else:
#若元素在字典中不存在,则该元素首次出现
self.dict1[val]={slen}
return True
def remove(self, val: int) -> bool:
"""
Removes a value from the collection. Returns true if the collection contained the specified element.
"""
slen=len(self.list1)
vset=self.dict1.get(val)
if vset:
last_val=self.list1[-1]
if val==last_val:
#将列表中最后一个插入的val,从键值中移除
vset.remove(slen-1)
else:
#用列表中最后一个元素复制到 val所在的其中一个位置vindex处,并更新最后一个元素的键值集合
vindex=vset.pop()
self.list1[vindex]=last_val
last_set=self.dict1.get(last_val)
last_set.remove(slen-1)
last_set.add(vindex)
#将列表中最后一个元素删除
self.list1.pop()
return True
return False
def getRandom(self) -> int:
"""
Get a random element from the collection.
"""
return random.choice(self.list1)
# Your RandomizedCollection object will be instantiated and called as such:
# obj = RandomizedCollection()
# param_1 = obj.insert(val)
# param_2 = obj.remove(val)
# param_3 = obj.getRandom()