📌  相关文章
📜  设计一个支持O(1)时间内插入和第一个非重复元素的结构(1)

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

设计一个支持O(1)时间内插入和第一个非重复元素的结构

在这个题目中,我们需要设计一个数据结构,该数据结构需要支持以下操作:

  • O(1)时间内插入元素
  • O(1)时间获取第一个非重复元素
题目分析

我们可以使用一个哈希表来维护元素的出现次数和元素出现的顺序。对于哈希表中的每一个元素,我们可以使用一个双向链表来维护它在列表中出现的位置。这个双向链表中的每一个节点既包含当前元素的值,还包含此元素在列表中的出现次数。

在插入一个新元素时,我们需要判断当前元素是否已存在。如果已经存在,我们将此元素在哈希表中的出现次数加一即可。如果当前元素不存在,则我们需要在双向链表的末尾添加一个新节点,并将此节点的值设置为当前元素,出现次数设置为1。同时,在哈希表中也需要添加此元素,并将其出现次数设置为1。

获取第一个非重复元素时,我们只需要遍历双向链表,找到第一个出现次数为1的节点即可。

代码实现

下面是一个简单的 Python 实现:

class FirstUnique:
    def __init__(self):
        self.head = Node(0)
        self.tail = Node(0)
        self.head.next = self.tail
        self.tail.prev = self.head
        self.table = {}
        
    def add(self, value):
        if value in self.table:
            node = self.table[value]
            node.count += 1
            self.remove(node)
        else:
            node = Node(value)
            node.count = 1
            self.table[value] = node
            self.add_to_tail(node)
        
    def add_to_tail(self, node):
        prev = self.tail.prev
        prev.next = node
        node.prev = prev
        node.next = self.tail
        self.tail.prev = node
        
    def remove(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev
        
    def first_unique(self):
        if self.head.next == self.tail:
            return None
        return self.head.next.value if self.head.next.count == 1 else None
        
        
class Node:
    def __init__(self, value):
        self.value = value
        self.count = 0
        self.prev = None
        self.next = None

在这个实现中,我们定义了一个 FirstUnique 类,类中有一个 Node 类来定义双向链表的节点。在 FirstUnique 类中,我们使用 head 和 tail 来指向双向链表的头节点和尾节点。当添加一个新元素时,我们首先在哈希表中查找该元素是否存在。如果存在,我们将该元素在双向链表中的节点删除,并将其出现次数加一。如果不存在,则向双向链表的尾部添加一个新节点,并在哈希表中添加该元素。获取第一个非重复元素时,我们只需要判断头节点的 next 是否为尾节点,如果是,说明链表为空,返回 None。否则,我们遍历链表,找到第一个出现次数为1的节点并返回其值。

性能分析
  • 插入操作的时间复杂度为 O(1),因为我们可以直接在双向链表的尾部添加一个新节点,并在哈希表中添加一个新元素。
  • 获取第一个非重复元素的时间复杂度为 O(n),因为在最坏情况下,整个列表中没有唯一的元素,我们需要遍历整个链表才能找到答案。但是,由于在插入操作时我们已经将每个元素出现的次数记录在了哈希表中,因此大部分情况下,获取第一个非重复元素的时间复杂度都会比较小。
参考资料