【剑指offer学习记录】9-两个栈实现队列

9-两个栈实现队列

题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

题目分析

栈的逻辑是先进后出

队列的逻辑是先进先出

所以本题的本质是两种逻辑的转换

  • 两栈分工

    使用stackA作为入队列容器,stackB作为出队列容器。

    当入队列时,push到stackA中;

    当出队列时,当stackB为空时,下一个出队列元素为入队列时的第一个元素,即stackA中栈底元素,此时将stackA中元素依次pop出来并push到stackB中,此时stackB的栈顶为入队列的第一个元素,即为此时的出队列元素。

    当出队列时,当stackB不为空时,由前一种情况可知,此时stackB中的元素由顶到底为队列的入队顺序,则此时直接pop出stackB中的栈顶元素

代码实现

 
 1 class Solution:
 2      def __init__(self):
 3          self.stackA = []
 4          self.stackB = []
 5      def push(self, node):
 6          self.stackA.append(node) #list的append是加在队尾
 7      def pop(self):
 8          if self.stackB:
 9              # list的pop是最后一个元素,就是栈顶,因此list本身就是一个stack逻辑的结构
10              return self.stackB.pop() 
11          else:
12              while self.stackA:
13                  #stackA弹出的元素压入stackB中
14                  self.stackB.append(self.stackA.pop())
15              return self.stackB.pop()

 


         

9- 题目拓展-用两个队列实现一个栈

  • 两队列分工

    queueA作为入栈队列,queueB作为出栈队列

    入栈时,直接将元素加入queueA;

    出栈时,当queueB为空,此时出栈元素为入queueA最后一个元素,将queueA元素全部取出加入queueB,此时queueB第一个元素为栈顺序的出栈第一个元素,queueB第一个元素出队列;

    出栈时,当queueB不为空,如果此时queueA也不为空,则出栈元素仍为queueA最后一个元素;

    出栈时,当queueB不为空,queueA为空,此时出栈元素为queueB的第一个元素。

  • 方法一(建议)

    • pop

      判断如果队列A只有一个元素,则直接出队。否则,把队A中的元素出队并入队B,直到队A中只有一个元素,再直接出队。为了下一次继续操作,互换队A和队B。

      原理:两个队列AB交换不会影响AB中元素的顺序,同时把A中的元素放入B中也不会影响A中元素原来的顺序。所以每次A中只剩一个元素就是第一个入A的元素,而B中元素的顺序仍为原来A中元素的顺序。

    • push

      直接入队

  • 方法二(不建议)

    • push关键思路

      为了保证先进栈的元素一直在栈底,需要将两个队列交替使用,才能满足需求。因此,想法是,我们只在空的那个队列上添加元素,然后把非空的那个队列中的元素全部追加到当前这个队列。这样一来,我们又得到一个空的队列,供下一次添加元素.

    • pop

      因为在添加元素时,我们已经按照进栈的先后顺序把后进栈的元素放在一个队列的头部,所以出栈操作时,我们只需要找到那个非空的队列,并依次取出数据即可。

 

代码实现

 
 1 #方法一
 2  class Solution:
 3      def __init__(self):
 4          self.queueA = []
 5          self.queueB = []
 6      def push(self, node):
 7          self.queueA.insert(0, node)
 8      def pop(self):
 9          if not self.queueA:
10              return None
11          while len(self.queueA)!=1:
12              self.queueB.insert(0, self.queueA.pop())
13          self.queueA, self.queueB = self.queueB, self.queueA
14          
15          '''
16          while len(self.queueA)!=1:
17              self.queueB.append(self.queueA.pop(0))
18          list中pop(0)可以弹出指定位置的元素
19          '''
20          return self.queueB.pop()
21          

 

posted @ 2020-07-15 20:36  szxyx  阅读(113)  评论(0编辑  收藏  举报