题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
解题思路
牛客网上的《剑指offer》中这道题的Java代码示例给了需要的两个栈,但Python代码示例需要我们自己定义这两个栈。根据题目,要求两个栈来实现队列的Push和Pop操作,已知栈是后入先出型,队列是先入先出型,需要利用栈后入先出的特点实现队列先入先出的特点。
思路1
分析这道题时,最先想到的解题思路是:两个栈分别负责入栈和出栈,当需要出栈时,将所有数据转移到负责出栈的栈中,再进行出栈操作;当需要入栈时,将所有数据转移到负责入栈的栈中,再进行出栈操作。这样可以利用两个栈实现数据的先入先出的特性。
Python代码1
class Solution:
def __init__(self):
self.stackIn = []
self.stackOut = []
def push(self, node):
while self.stackOut:
self.stackIn.append(self.stackOut.pop(-1))
self.stackIn.append(node)
def pop(self):
while self.stackIn:
self.stackOut.append(self.stackIn.pop(-1))
return self.stackOut.pop(-1)
虽然这种思路非常直观易懂,但当频繁地进行入栈+出栈操作时,绝大多数非栈顶的数据将无意义地在两个栈中移动,相当浪费存储空间和时间。
思路2
事先说明这个信息:入栈时数据存入栈stackIn, 出栈时数据从stackOut弹出。执行入栈操作时,将数据源源不断的压入栈stackIn;执行出栈操作时,将stackIn的数据一次性全部弹出,存入到stackOut中。当stackOut栈非空时,不断弹出stackOut栈中的数据顺序即为队列的Pop顺序;当stackOut中的数据为空后,再将新入栈stackIn的数据一次性存入stackOut中即可。相比于上一种方式,这种方式极大降低了数据在栈stackIn和栈stackOut中来回无意义的腾挪操作,占据更低的存储空间,消耗更低的运算时间。
Python代码2
class Solution:
def __init__(self):
self.stackIn = []
self.stackOut = []
def push(self, node):
self.stackIn.append(node)
def pop(self):
if not self.stackOut:
while self.stackIn:
self.stackOut.append(self.stackIn.pop(-1))
return self.stackOut.pop(-1)
最后给出验证代码。要求出栈的顺序是1–>2–>3–>4–>5.
class Solution:
def __init__(self):
self.stackIn = []
self.stackOut = []
def push(self, node):
self.stackIn.append(node)
def pop(self):
if not self.stackOut:
while self.stackIn:
self.stackOut.append(self.stackIn.pop(-1))
return self.stackOut.pop(-1)
if __name__ == '__main__':
solution = Solution()
solution.push(1)
solution.push(2)
solution.push(3)
solution.pop()
solution.pop()
solution.push(4)
solution.pop()
solution.push(5)
solution.pop()
solution.pop()