【问题标题】:How to remove maximum value from collection with 'O(log n)'_ time complexity?如何从具有'O(log n)'_时间复杂度的集合中删除最大值?
【发布时间】:2019-08-16 14:06:16
【问题描述】:

我有一个集合,但我还不知道要使用哪种数据结构。 我有两个函数,添加和删除。

这两个函数都需要具有相似的复杂性,因为它们都被频繁使用。

要么添加函数很简单,因为 O(1) 和 removeMax 将是 O(log n) 或者两者都是 o(1) 或者其中一个是 log n 和另一个 o(n)。

removeMax 应该移除最大值并返回它,并且应该能够多次使用它,所以下次你调用它时它会移除下一个新的最大值。

有没有办法同时使用 O(1) 或至少 log n 来删除?

【问题讨论】:

  • 该集合大概是并且必须是未排序的?
  • @Michael 是的,它是未排序的,随机的
  • 您在寻找斐波那契堆(或其他类型的最大堆)吗? en.wikipedia.org/wiki/Fibonacci_heap - O(1) 插入,O(logn) 删除(当然摊销)
  • 看看最小-最大堆。我相信优先级队列在内部使用其中之一。
  • Maybe useful,关于@OndraK 的评论。

标签: java collections time-complexity


【解决方案1】:

如果是排序结构(例如TreeSet),addremove 都需要O(logN)

如果未排序,add 可以在 O(1) 中实现,但 removeMax 将采用 O(N),因为您必须检查所有元素以在未排序的数据结构中找到最大值。

【讨论】:

  • TreeSet 会自动对您的收藏进行排序吗?它是什么 TreeSet 其中变量的 getValue 为整数,它会自动知道如何排序吗?
  • @BenBeri 是的。如果 TreeSet 的元素类型实现了 Comparable,那将定义排序。否则,您可以为 TreeSet 构造函数提供一个比较器,它将定义排序。
  • @BenBri 您将在插入时进行排序,因此您当时不必担心太多(插入时将需要 O(nlogn) 而不是 O (n) 为您第一次输入整个输入,之后每次插入删除都遵循 O(logn)。但请记住,树集将丢弃重复的元素。
【解决方案2】:

Max heaps 可能是您正在寻找的,remove 操作的摊销复杂度为 O(logn)。 Fibonacci heap(请参阅此 great animation 以了解其工作原理)似乎适合您的数据结构,因为它对于 insert 和所有其他操作具有 O(1)。遗憾的是,它的实现不是标准 Java 库的一部分,但是可以找到大量的实现(例如,请参阅 @Lino 评论中的 answer)。

Guava's implementation of min-max heap

【讨论】:

    【解决方案3】:

    如果你需要一个数据结构在 O(logn) 中同时执行 add() 和 removeMax(),那么你只需要一个排序数组。对于 removeMax() 和 add(),您可以使用二进制搜索来查找目标值。 (对于删除,你找到最大值。对于添加,你找到小于你要插入的最大值,然后插入它的值)。时间复杂度都是O(logn)。

    【讨论】:

      猜你喜欢
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 2015-05-25
      相关资源
      最近更新 更多