有没有办法在O(1)中找到max并在O(lgN)中进行查找?

时间:2012-06-14 17:40:12

标签: performance algorithm data-structures big-o max

假设你有很多(关键,值)对象要跟踪,有很多插入和删除。

您需要满足3个要求:

  1. 在任何时候以恒定时间获取最大密钥
  2. 以对数时间查找任意键的值。
  3. 插入和删除采用对数时间。
  4. 是否有可以执行此操作的数据结构?

    我的想法:

    优先级队列可以在恒定时间内获得最大值,但我无法查找值。 二进制搜索树(2-3树)可以在对数时间内查找,但max也需要O(lgN)。 如果我试图跟踪BST中的最大值,当我必须删除最大值并找到第二个最大值时需要O(lgN)。

9 个答案:

答案 0 :(得分:10)

为什么我们需要那些奇特的数据结构?我认为跟踪Max节点的简单二进制搜索树可以很好地满足OP的要求。

  1. 您可以使用max key跟踪节点:

    无论何时插入新节点,都要将密钥与先前的最大密钥进行比较,以确定这是否是新的最大节点

    每当删除最大节点时,需要O(logN)才能找到下一个最大节点

  2. 你当然有O(logN)查询时间与BST的性质

  3. BST的更新需要O(logN)时间

答案 1 :(得分:4)

您可以并行使用两个数据结构 -

  1. 将键/值对存储在哈希表或平衡BST中以获取O(log n)查找,
  2. 将所有值存储在最大堆中,以便您可以在O(1)时间内查找最大值。
  3. 这使得插入或删除花费O(log n)时间,因为这是从最大堆插入或删除的时间复杂度。

    希望这有帮助!

答案 2 :(得分:3)

跳过列表有一个摊销的O(logn)查询,它们是一个链接列表,因此minmax始终为O(1)http://en.wikipedia.org/wiki/Skip_list

答案 3 :(得分:1)

我知道哈希表有O(1)搜索时间,因为您使用密钥并且您可以立即查找该值。就最大值而言,您可以在每次插入或删除值时始终跟踪该值。

答案 4 :(得分:1)

列表按降序排序怎么样?

  1. Max总是第一个所以O(1)。
  2. 通过二分搜索查找O(log n)。
  3. 插入/删除为O(n),因为在从位置i插入/删除时,您必须移动n-i个项目。

答案 5 :(得分:1)

由于您正在使用键值对,我建议您使用最佳解决方案在Java中使用TreeMap。

您可以简单地使用Treemap中的以下4种方法。

  • get()和put(key,value)方法用于插入和检索
  • lastKey()用于查找最大密钥。
  • 删除(密钥)以进行删除。

。或者 使用this page

中的以下结构

最终结论:

如果您要牺牲空间复杂性并热衷于运行时间,则需要拥有2个数据结构。

使用具有O(1)的HashMap或TreeMap进行插入,检索和删除。

然后根据我提供的第二个链接使用两个堆栈数据结构来查找o(1)的最大值或最小值。

我认为这是我能提供的最佳解决方案。

答案 6 :(得分:0)

查看 RMQ (范围最小 - 最大查询)数据结构或段树数据结构。它们都有一个O(1)查询时间,但你必须以某种方式修改它们来存储值..

这篇文章很http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor

答案 7 :(得分:0)

正如第一条评论所说,使用最大堆。使用 hashmap 将指针存储到堆中。这些用于恒定时间查找和日志时间删除。

堆很容易实现。它们不像BST那样需要平衡。哈希映射通常以您选择的语言构建。

答案 8 :(得分:0)

树数据结构中的删除已经是O(logN)操作,因此寻找第二个最大的键不会改变操作的复杂性。

尽管如此,你可以使元素无效而不是删除,如果你在数据结构中保留指针,那么从最大到最大的移动可能是O(N)操作。