使用 2 个堆栈实现队列,具有恒定的时间复杂度
Posted
技术标签:
【中文标题】使用 2 个堆栈实现队列,具有恒定的时间复杂度【英文标题】:implement queue using 2 stacks, with constant time complexity 【发布时间】:2021-12-24 03:15:46 【问题描述】:我想知道是否可以使用两个堆栈来实现一个队列,这样每个队列操作都需要摊销的常数时间。
【问题讨论】:
【参考方案1】:class QQ:
def __init__(self):
self.s = []
self.ss = []
def enque(self, val):
self.s.append(val)
def deque(self):
if not self.s and not self.ss: return None
if not self.ss:
while self.s:
self.ss.append(self.s.pop())
return self.ss.pop()
当我们将s
的元素弹出到ss
中时,第二个堆栈ss
以相反的顺序保存第一个堆栈s
的内容。反向堆栈只是一个队列。每当ss
为空时,我们将s
中的所有元素加载到ss
中。如果它不为空,我们只需 deque
从中提取一个元素。
时间复杂度是摊销常数,因为我们只对enque
ing 进行了一次移动,而从长远来看,deque
ing 只进行了两次移动。
【讨论】:
谢谢,但是这里deque()的复杂度不是O(1) 如果将 while 循环更改为 0:self.s.length,那么,由于我们知道重复次数,复杂度将为 O(1) 乘以等于 O(1) 的常数。但无论如何,我要感谢你帮助我。deque
具有摊销的O(1)
时间复杂度。也许你不熟悉python。 while self.s
,其中s
是一个列表,执行您使用0:self.s.length
描述的内容。当self.s
拥有任何成员时,这是真的。当它为空时,它会破裂。【参考方案2】:
我们使用 2 个带有标签“前”和“后”的堆栈。
在栈前我们应该使用size和clear方法,size返回栈的指针,clear设置指针为0。
对于enqueue()
,我们应该将新元素推送到前端堆栈。所以时间复杂度将是O(1)
。
对于dequeue()
,如果后栈为空,我们应该用前栈中的元素填充它,对于前栈中的每个元素,我们应该调用pop()
函数,然后使用push()
函数将其插入后栈,因为我们知道前栈的大小(并且它是恒定的)并且pop和push函数的时间复杂度为O(1)
,所以出队的整体复杂度将是O(1)
。
对于size()
,它将返回前堆栈和后堆栈的总和size()
。
对于isEmpty()
,它应该返回大小是否等于零。
【讨论】:
以上是关于使用 2 个堆栈实现队列,具有恒定的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章