使用两个堆栈实现队列或优先级队列并不难。
现在问题是
他们甚至可能吗?
P.S。当然,如果需要,你应该使用除{one}堆栈之外的constant
额外空间
答案 0 :(得分:3)
不,仅使用通过堆栈接口提供的方法(即仅使用push和pop方法)并不能使用恒定的额外空间。 [1]
考虑尝试使用堆栈模拟队列。
当排队时,如果我们只是简单地推入堆栈,我们将最终得到另一个我们需要做的事情的元素来到队列的前面以获得队列。很容易看出,一堆排队将使下一个队列不可能占用恒定的空间,因为所有这些排队的元素都需要弹出才能到达队列的前面。我们也可以将排队元素从堆栈顶部放入一定数量的元素,但这对它们来说也没有多大帮助 - 它下面的元素需要先出列,所以我们遇到了同样的问题。尝试将排队的元素放在堆栈顶部的恒定数量的元素之外,当然需要不止一定量的空间。
现在考虑一个优先级队列,其中每个新项目的优先级低于队列中已有的所有项目。这与简单队列同义,从上面的参数来看,无法使用具有常量空间的单个堆栈来模拟。
[1]:如果堆栈实现为数组或链表,就像通常那样,当然可以使用这些功能,但我确信这不是你所要求的。
答案 1 :(得分:0)
假设您将n
元素推送到堆栈中。现在你想要它底部的元素(如果你想实现一个队列)。您将需要额外的O(n)空间来保留其他n-1
元素,以便您可以访问底部元素。
=>在您的约束下,只有堆栈接口方法,您无法使用单个堆栈和常量空间来实现队列。
答案 2 :(得分:0)
如果您只允许标准堆栈操作(pop
,push
),则无法执行任务,因为排队项目意味着从堆栈中弹出所有项目,推送新项目,然后推回所有项目。如果您使用恒定时间,则无法弹出所有项目并使用O(1)
内存跟踪它们。
假设你实现了一个带有双向链表的堆栈并允许reverse
方法 - 意味着你翻转堆栈的顺序(链表的尾部变成尾部)。
现在,对于常规队列,您可以执行:
queue
- 再次执行reverse
,push
新项目和reverse
。
dequeue
- 执行pop
。
请注意,一旦允许reverse
操作,它就不再是标准堆栈了。
即使您允许reverse
,仍然无法实现优先级队列,因为您在排队或出队时仍需要执行各种比较,并且仍然会遇到无法存储空间的问题你要比较的项目。
答案 3 :(得分:0)
这是一个技术上正确的解决方案,但几乎肯定对您的目的毫无用处。
我们使用堆栈S
队列(常规或优先级)。我们初始化S
以保留一个空队列。对于任何队列操作,我们查看S
的顶部元素并将队列操作应用于其中。这样,S
将只保留一个元素。
如果您认为堆栈“拥有”其所有元素的内存,那么它在堆栈外部使用零内存。