【问题标题】:extractMin operation in O(1) using 2 stacks使用 2 个堆栈在 O(1) 中进行 extractMin 操作
【发布时间】:2016-04-14 23:58:29
【问题描述】:

给定一个连续的整数流和两个堆栈。我想实现以 O(1) 复杂度运行的 extractMin 操作。此操作从记录中弹出最小元素并将其返回。基本解决方案是使用 2 个堆栈以反向排序顺序保持数据。这样我们就可以简单地弹出包含数据的栈顶元素。但是有了这个,每个整数的插入都是 O(N) 。我能否在插入中获得更好的复杂性,保持 extractMin 操作为 O(1)。

添加示例以使其更清晰:

10,-2​​0,2,-3,-5,10,20(随时为整数流)。

extractMin() // returns -20
extractMin() // returns -5

【问题讨论】:

  • 可以push一个数组,然后按排序顺序弹出,这样排序下界就生效了。
  • 您的问题是,是否可以使用两个堆栈,或者是否可以使用任何合适的数据结构?
  • 另外,您希望混合插入和弹出,还是先插入所有内容,然后开始弹出?
  • 这是在一次采访中被问到的。不确定是否不可能。
  • @hyde 混合插入和弹出

标签: c++ algorithm stack time-complexity


【解决方案1】:

使用堆栈无法获得更好的复杂性。即使您要求使用堆栈进行常量提取,但问题的措辞似乎并未明确禁止使用其他数据结构。

在我的答案的早期版本中,我建议使用最小堆,它通过堆的构建平均插入恒定(在最坏的情况下,单个插入是对数的)。然而,堆不允许持续提取,而只能是对数。

要获取多个值的常量提取,您需要对所有值进行排序。以比堆栈更好的复杂性实现这一点的一种方法是构建二叉搜索树,同时跟踪最小节点。使用平衡的bst,可以实现对数插入。要获得恒定的单独提取,您还需要在每个节点中存储一个父指针。但如果只需要按顺序遍历所有值,则不需要指针。

【讨论】:

  • 你确定 O(1) 平均值吗?据我了解,它可以用于 O(n) 平均时间比较排序,这被证明是不可能的。
  • @sbarzowski(删除了我之前的 cmets 以获得更好的回复)您怀疑我的复杂性分析是正确的,因为它们确实允许线性排序。插入是conśtant in average。但我保证 extract 保持不变,但事实并非如此。
  • 我认为平衡 bst(带有父链接)可以提供分摊的 O(log N) 插入(其中 N 是树的最大大小),但细节非常棘手。特别是,您必须在一系列 pop 之后的下一次插入之前重新平衡树。
猜你喜欢
  • 2012-08-17
  • 2019-05-09
  • 2011-06-17
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
相关资源
最近更新 更多