【问题标题】:In a min-heap with n elements with the smallest element at the root,在具有 n 个元素的最小堆中,最小元素在根处,
【发布时间】:2020-04-28 16:10:31
【问题描述】:

在有n个元素的最小堆中,最小的元素在根,可以及时找到第7小的元素。

  1. Θ(nlogn)
  2. Θ(n)
  3. Θ(logn)
  4. Θ(1)

我的理解: 在最小堆检索操作中找到最小元素的时间 - Θ(1) 在最小堆上找到第二小的元素的时间需要 22−1 = 3 次检查操作来找到 3 个元素中的第二小元素 - Θ(1)。

找到第 7 个最小元素的时间 - 需要 O(27−1) = O(127) 个检查操作才能在 127 个可能的元素中找到第 7 个最小元素 - Θ(1)。

简而言之,如果所需操作的数量与输入大小 n 无关,那么它总是 Θ(1)。 (在这里,我们正在对堆进行级别顺序遍历并检查元素)。

或者我也可以这样看:如果我们不允许遍历堆并且只允许默认的堆操作,我们将被限制执行 Extract-min 7 次,这将是 O(n)。

我的疑问是哪种方法是正确的,应该是什么答案。

【问题讨论】:

  • 是否要在不修改堆的情况下找到项目?还是可以只删除最少的项目七次?
  • 数据是否封装不可访问?如果您可以直接检查底层数组,您可以在不改变堆的情况下直接看到常数时间的前 127 个元素,而 Matt Timmermans 的答案应该是正确的。请记住,大 O 是关于问题如何作为 n 的函数进行扩展,而不是关于给定 n 需要多长时间,因此即使常数很大,也会被忽略。

标签: algorithm time-complexity


【解决方案1】:

在最小堆中提取 min 需要 log(n) 时间,并且因为您限制在第 7 个位置(一个常数),所以所用时间仍然是 log(n) 的顺序。

如果您试图找到第 7 个最小的元素,一种方法是从堆中提取顶部元素 6 次,然后读取(而不是提取)堆顶部。那是你的第 7 个最小的元素。您的运行时间仍然是 log(n) 的顺序,因为您要从堆中删除固定次数。现在您可能想要将 6 个元素重新插入堆中。每个插入的最差时间为log(n),这仍然是log(n),因为6 是常数。

【讨论】:

  • 所有这些都是正确的,但是由于第 7 个最小的项不能超过堆的 7 层,它是前 127 个元素之一,并且与 n 无关。因此,它总是可以在 O(1) 时间内找到,尽管常数很大。对于足够大的 n,这将击败 O(log n)。
  • @pjs 没错。一般复杂度为 O(k log n)。找到第 k 个最小的可以在 O(n) 时间内完成(快速选择),但它会破坏堆。当然,重建堆也是 O(n)。
【解决方案2】:

最小堆是节点的特定排列,您可以遍历它以在 O(1) 时间内找到第 7 个最小的元素,因为您最多必须访问 127 个节点。

优先级队列是一种提供最小提取操作的抽象数据类型,但不一定使用可以通过这种方式遍历的最小堆来实现。

【讨论】:

  • 如果输入有 127 1s、127 2s、127 3s 127 4s 127 5s 127 6s 和一个 7 怎么办?在这种情况下第 7 个最小的元素是 7,在这种情况下我们如何遍历?
  • @SomeDude 在这种情况下,您将在访问不超过 127 个节点后证明您最小的 7 个元素都是 1。
猜你喜欢
  • 2018-11-29
  • 2019-04-11
  • 2020-05-08
  • 2014-05-07
  • 1970-01-01
  • 2012-08-16
  • 2020-08-09
  • 2013-12-22
  • 2021-05-27
相关资源
最近更新 更多