数据结构,支持类似操作和模式查找的队列

时间:2013-09-27 14:49:45

标签: algorithm data-structures heap hashtable

这是几乎3年前向我询问的一个面试问题,我正在思考这一段时间。

  

设计支持以下操作的数据结构:   insert_back(),remove_front()和find_mode()。最复杂   必需的。

我能想到的最佳解决方案是O(logn)用于插入和删除,O(1)用于模式。这就是我解决它的方法:保留一个队列DS来处理插入和删除的元素。 还要保留一个最大堆排序的数组和一个哈希表。 哈希表包含一个整数键和该元素的堆数组位置的索引。堆数组包含一个有序对(count,element),并在count属性上排序。

插入:将元素插入队列。从哈希表中查找堆数组索引的位置。如果不存在,则将元素添加到堆中并向上堆积。然后将最终位置添加到哈希表中。增加该位置的计数并根据需要向上或向下堆积以恢复堆属性。

删除:从队列头部删除元素。从哈希表中,找到堆数组索引中的位置。减少堆中的计数并根据需要向上或向下重新调整以恢复堆属性。

查找模式:数组堆头部的元素(getMax())将为我们提供模式。

有人可以提出更好的建议。我能想到的唯一优化是使用Fibonacci堆,但我不确定这是否适合这个问题。

1 个答案:

答案 0 :(得分:2)

我认为所有操作都有O(1)的解决方案。

你需要一个双端队列和两个哈希表。

第一个是链接的哈希表,每个element存储其countnext元素按计数顺序,previous元素按计数顺序存储。然后,您可以在恒定时间内查看该哈希表中的下一个和上一个元素的条目。对于此哈希表,您还可以保留并更新具有最大计数的元素。 (element -> count, next_element, previous_element

在每个不同数量的元素的第二个哈希表中,您将具有该计数的元素存储在第一个哈希表中的范围的开头和结尾。请注意,此哈希表的大小将小于n(我认为它是O(sqrt(n)))。 (count -> (first_element, last_element)

基本上,当你向deque中添加一个元素或从中删除一个元素时,你可以通过分析它的nextprevious元素以及它们的值来在第一个哈希表中找到它的新位置。在常量时间内第二个哈希表中的旧计数和新计数。您可以使用链接列表的算法以恒定时间在第一个哈希表中删除和添加元素。您还可以在常量时间内更新第二个哈希表和具有最大计数的元素。

如果需要,我会尝试编写伪代码,但在许多特殊情况下它似乎相当复杂。