【问题标题】:Queue using 2 stacks, deletion in O(1)使用 2 个堆栈进行队列,在 O(1) 中删除
【发布时间】:2012-08-17 03:47:43
【问题描述】:

我在 Java 中使用 2 个堆栈实现了一个队列,我遵循这个算法:

enQueue(x)
将 x 推入 stack1

deQueue()
1) 如果两个堆栈都是空的,则错误。
2) 如果 stack2 为空而 stack1 不为空,则将 stack1 中的所有内容推送到 stack2。
3) 从stack2中弹出元素并返回。

现在,这里的问题是第一个deQueue() 操作非常慢(因为它将所有内容都转移到stack2)。我们可以以某种方式修改算法,使deQueue 始终为 O(1) 吗?还有其他选择吗?

【问题讨论】:

  • 您使用什么数据模型来存储队列?
  • 你已经拥有的是摊销 O(1)。

标签: java algorithm data-structures


【解决方案1】:

您可以交换两个堆栈。

deQueue()

  1. 如果两个堆栈都是空的,则错误。
  2. 如果 stack2 为空,则 stack1 不为空,交换两个栈。
  3. 从 stack2 并返回它。

使用交换,操作总是 O(1)

如果您需要一个 FIFO 队列,请使用两个队列。仅当您需要 LIFO 行为时才使用堆栈。

如果是这样的话,使用一个队列和两个队列没有区别,所以你也可以只使用一个队列。如果您使用线程,请使用包装队列和线程池的 ExecutorService。

【讨论】:

  • 然后enqueue(1); enqueue(2); dequeue() 返回2,不是吗?我希望它返回1
  • "将所有内容从 stack1 推送到 stack2。"我假设这意味着一次取一个元素并推送到堆栈 2,这将颠倒堆栈的顺序。
  • 在这种情况下,使用堆栈是没有意义的,因为两个 LIFO 构成一个 FIFO 队列。
  • 我认为这是一个面试问题——我之前至少在一次面试中听过这个问题(但没有 O(1) 限制)
【解决方案2】:

我会咬:为什么不使用双向链表?这应该是 O(1) 推送和 O(1) 弹出。

【讨论】:

  • 请注意,java.util.LinkedList 实现了 Queue 和 Deque 接口。
【解决方案3】:

当我们说first deQueue() operation is very slow (since it transfers everything to stack2).

我假设我们正在谈论这个

2) 如果 stack2 为空而 stack1 不为空,则从 stack1 到 stack2。

我们是否只是以相同的顺序将 stack1 中的所有内容转移到 stack2 中。这将是简单的分配 (stack2=stack1;),因此是 O(1)。

或者,如果我们说我们需要从 stack1 中逐一弹出所有内容,然后添加到 stack2。我们基本上是在讨论反转一个列表(stack1),并分配给 stack2(我们知道,分配是 O(1))。有多种很好的算法可以反转列表http://www.codeproject.com/Articles/27742/How-To-Reverse-a-Linked-List-3-Different-Ways

如果您使用 Java(根据标签),您可以简单地使用 Collections.reverse(arrayList); 来反转列表。

【讨论】:

    猜你喜欢
    • 2016-04-14
    • 2011-11-29
    • 2018-11-13
    • 2014-12-23
    • 2018-08-05
    • 1970-01-01
    • 2019-05-09
    • 2012-02-02
    • 2021-11-21
    相关资源
    最近更新 更多