标题
1. 题目
题目一:用两个栈来实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能。
题目二:用两个队列来实现一个栈。
2. 解题思路
2.1 思路1
一个栈负责元素写入,一个栈负责元素弹出,只有当弹出栈中没有元素时才将写入栈中的元素依次加入到弹出栈中。
还有一种方法(没写实现代码)是,利用用第二个栈将元素的顺序颠倒过来,变成队列的弹出顺序:
1, 2, 3, 4 – 队列 --> 1, 2, 3, 4
1, 2, 3, 4 – 经过 栈1变为 4, 3, 2, 1 --经过 栈2变为 1,2 ,3 ,4
这样就通过两个栈实现了一个队列。
2.2 思路2
思路2是针对题目2的。认为左边为栈底,右边为栈顶
依次添加元素1, 2, 3, 4,依次弹出元素4, 3, 2, 1
队列1:1, 2, 3, 4
队列2:空
队列1:4(弹出4)# 把1, 2, 3都转移到队列2中,此时可弹出4
队列2:1, 2, 3
3. 代码实现
3.1 解法一
思路1的代码实现如下所示:
class CQueue:
def __init__(self):
self._in_stack = [] #元素push到这个栈中
self._out_stack = [] #元素从这个栈中pop
def appendTail(self, value: int) -> None:
"""
入队
"""
self._in_stack.append(value)
def deleteHead(self) -> int:
"""
出队
"""
if self._out_stack:
return self._out_stack.pop()
elif self._in_stack:
for i in range(len(self._in_stack)):
self._out_stack.append(self._in_stack.pop())
return self._out_stack.pop()
return -1
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()
3.2 解法二
思路2的代码实现如下所示:
class CStack:
"""
始终保持两个队列中有一个队列为空队列
每次添加元素时,往不为空的队列中添加
每次弹出栈顶元素时,将该不为空的队列中除最后一个元素外,依次转移到不为空的队列中,只留下最后一个元素,弹出此元素
重复上面的过程。
"""
def __init__(self):
self._queue1 = []
self._queue2 = []
def appendTail(self, value):
"""在尾部添加元素"""
if self._queue1:
self._queue1.append(value)
else:
self._queue2.append(value)
def deleteTail(self):
"""在尾部删除元素"""
if self._queue2:
for i in range(len(self._queue2)-1):
self._queue1.append(self._queue2.pop(0))
return self._queue2.pop()
elif self._queue1:
for i in range(len(self._queue1)-1):
self._queue2.append(self._queue1.pop(0))
return self._queue1.pop()
return -1
4. 总结
掌握栈和队列这两种数据结构的特性,再通过纸上举例、画图来分析如何实现。
5. 参考文献
[1] 剑指offer丛书
[2] 剑指Offer——名企面试官精讲典型编程题