题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例1:
输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出:[null,null,3,-1]
示例 2:
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
我的想法1:
在init中初始化两个栈,在appendTail()中,先使用空栈来存新数据,然后将另一个栈中的全部数据转入原本为空现在只有一个元素的栈中。在deleteHead()中,判断哪个栈不为空,弹出不为空的栈的栈顶元素。
两个示例都能正常输出,但是当连续输入多个数据时,就会发生问题。
例如下面这组数据:
["CQueue","deleteHead","appendTail","deleteHead","appendTail","appendTail","deleteHead","deleteHead","deleteHead","appendTail","deleteHead","appendTail","appendTail","appendTail","appendTail","appendTail","appendTail","deleteHead","deleteHead","deleteHead","deleteHead"]
[[],[],[12],[],[10],[9],[],[],[],[20],[],[1],[8],[20],[1],[11],[2],[],[],[],[]]
这其中,[1],[8],[20],[1],[11],[2],连续进栈,如果是按我的想法,在两个栈间来回倒腾元素,会是下面这种结果:
我们会发现,在最后一个2进栈时,从栈顶到栈底的顺序是:11→20→1→8→1→2,这个顺序与按队列先进先出的顺序不符合(先进先出:1→8→20→1→11→2),这其实是因为,当某部分数据从stack1挪到stack2,再从stack2挪回stack1时,顺序还是原来的顺序,并不会将新进来的数据压入栈底!
class CQueue:
def __init__(self):
self.stack1 = list()
self.stack2 = list()
def appendTail(self, value: int) -> None:
if self.stack1:
self.stack2.append(value)
while self.stack1:
self.stack2.append(self.stack1.pop())
print("stack1:",self.stack1)
print("stack2:",self.stack2)
else:
self.stack1.append(value)
while self.stack2:
self.stack1.append(self.stack2.pop())
print("stack1:",self.stack1)
print("stack2:",self.stack2)
def deleteHead(self) -> int:
if self.stack1:
print("stack1:",self.stack1)
return self.stack1.pop()
if self.stack2:
print("stack2:",self.stack2)
return self.stack2.pop()
return -1
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()
现在的想法是让新元素永远进入栈底,怎么做?
始终让stack1做主栈,让stack2做辅助栈:新元素进入stack1前,让stack1中的元素先进入stack2,等到新元素压入栈底,再将元素从stack2转运回stack1。
class CQueue:
def __init__(self):
self.stack1 = list()
self.stack2 = list()
def appendTail(self, value: int) -> None:
self.stack1.append(value)
# 保证在进入新数据时stack1永远为空
while self.stack1:
self.stack2.append(self.stack1.pop())
def deleteHead(self) -> int:
# 本来应该弹出stack1,但是我们偷懒,就不讲stack2中的数据转入stack1,于是应该从栈底输出数据
if self.stack2:
# 从栈底输出数据,使用pop(0)
return self.stack2.pop(0)
return -1