建议一个可以优化以下所有3个操作的数据结构:
假设您输入整数/数字。
答案 0 :(得分:11)
动态数组+ Hashmap = O(1)用于所有三个操作
追加到数组O(1)的尾部,并向Hashmap O(1)添加一个值索引对。
通过Hashmap O(1)中的值查找索引,按数组中的索引删除,并将最后一个元素交换到插槽O(1)中,并更新(以前用于)的值 - 索引对)最后一个元素O(1)。
为数组O(1)生成随机索引。
答案 1 :(得分:3)
python中的O(1):
from collections import defaultdict
from random import choice
class DataStructure(list):
def __init__(self):
self.values = []
self.locations = defaultdict(list)
def add(self, val):
i = len(self.values)
self.locations[val].append(i)
self.values.append(val)
assert self.values[i] == val
def delete(self, val):
locations = self.locations[val]
if locations:
i = locations.pop()
self.values[i] = self.values[-1]
self.values.pop()
def random(self):
return choice(self.values)
ds = DataStructure()
ds.add(3)
ds.add(5)
print ds.random()
print ds.random()
print ds.random()
print ds.random()
ds.delete(5)
print ds.random()
ds.delete(3)
"""
5
3
3
5
3
"""
See Time Complexities of List and Dict operations to Confirm
(注意pop是O(1),因为我们从列表的末尾弹出)
答案 2 :(得分:2)
使用带有open addressing的哈希表。必要时通过重新运行将负载因子保持在α和β之间。为了避免振荡,重新调整到α和β之间的某个值。大多数开放散列方案实现要求表是一个方便的大小,如2的幂或素数。 α和β的典型值可能为0.25和0.75,目标载荷系数为0.5。
开放寻址哈希表是O(1)查找,除非加载因子接近1,指数大小调整是分摊O(1),因此insert是分摊的O(1)。处理删除的最简单方法是lazy-delete:删除的元素被标记为已删除但未删除,因此可以在插入期间覆盖它们。同样,指数调整大小是分摊O(1),删除操作本身仅取决于查找。
随机选择完全绕过散列机制,只是随机插入底层数组,直到找到未删除的记录。由于载荷因子至少为α,预期的刺伤次数最多为1 /α,同样为O(1)。