📜  设计一个数据结构,该数据结构支持O(1)中具有重复项的insert,delete,getRandom(1)

📅  最后修改于: 2023-12-03 15:28:08.673000             🧑  作者: Mango

设计支持O(1)中具有重复项的数据结构

为了实现这样的数据结构,我们需要维护两个数据结构:

  • 一个哈希表,用于存储元素和它们在数组中的下标。
  • 一个动态数组,用于存储元素。

在哈希表中,我们将每个元素的值映射到一个数组中的下标。在动态数组中,我们按顺序存储元素,并在哈希表中为每个元素存储一个指向其在数组中的下标的指针。当我们要插入一个元素时,我们将它添加到数组的末尾,并在哈希表中为它创建一个指针。

  • 插入操作:在哈希表中搜索元素是否已经存在。
  1. 如果不存在,则将元素插入到数组的末尾,并在哈希表中为它创建一个指针。
  2. 如果存在,则在数组的对应位置插入元素。
  • 删除操作:首先在哈希表中搜索元素是否存在。
  1. 如果不存在,则返回。
  2. 如果存在,则在数组中找到该元素,并将其与最后一个元素交换位置,然后删除最后一个元素。最后,更新哈希表中的指针。
  • 随机访问操作(getRandom):从数组中随机选择一个元素。

由于我们使用动态数组来存储元素,所以随机访问操作发生在O(1)时间内。

下面是Python代码的实现:

class RandomizedCollection:
    def __init__(self):
        self.vals = []
        self.idx = defaultdict(set)
        
    def insert(self, val: int) -> bool:
        self.idx[val].add(len(self.vals))
        self.vals.append(val)
        return len(self.idx[val]) == 1
        
    def remove(self, val: int) -> bool:
        if val in self.idx:
            idx = self.idx[val].pop()
            last = self.vals[-1]
            self.vals[idx] = last
            self.idx[last].add(idx)
            self.idx[last].discard(len(self.vals) - 1)
            self.vals.pop()
            if not self.idx[val]:
                del self.idx[val]
            return True
        return False
        
    def getRandom(self) -> int:
        return choice(self.vals)

这里使用了Python内置的defaultdict来实现哈希表,并使用set来存储下标,以支持具有重复项的插入操作。insert操作在O(1)时间内完成,因为它只需要将元素添加到数组的末尾,并在哈希表中创建一个指针。remove操作在最坏情况下需要O(n)时间,其中n是元素的数量,但它通常执行得很快。getRandom操作在O(1)时间内完成,因为它只需要从数组中随机选择一个元素。

这个数据结构非常有用,并且可以用于许多问题,例如设计一个支持O(1)中删除最后K个元素的数据结构,其中K是一个固定的整数。