读者来到图书馆排队借还书,图书管理员使用两个书车来完成整理借还书的任务。书车中的书从下往上叠加存放,图书管理员每次只能拿取书车顶部的书。排队的读者会有两种操作:

push(bookID):把借阅的书籍还到图书馆。
pop():从图书馆中借出书籍。
为了保持图书的顺序,图书管理员每次取出供读者借阅的书籍是 最早 归还到图书馆的书籍。你需要返回 每次读者借出书的值 。

如果没有归还的书可以取出,返回 -1 。



示例 1:

输入:
["BookQueue", "push", "push", "pop"]
[[], [1], [2], []]
输出:[null,null,null,1]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.pop(); // return 1, queue is [2]


提示:

1 <= bookID <= 10000
最多会对 push、pop 进行 10000 次调用

自我解答

        自己没想出来,思考了两个方向:
                1、既然有两个栈,那么数据肯定得存到某个栈中,假设将数据存到  stack1,  那么怎么把栈底输出呢?
                      应该需要  stack2  来协助,那么怎么协助呢?  我知道应该输出的是  stack1[0],  那么我能否
                      使用  stack2  来存这个  “0”  呢?  就是使用  stack2  来存下标,
                      确保  stack2  的栈顶  ==  stack1  的栈底的下标。如果可以实现的话,似乎行得通。
                      可是,stack2  的下标,是依靠  stack1  的数据的,在  stack1进行压栈操作,数据在栈顶,
                      获得的下标也只能压到  stack2  的栈顶…这条路走不通
                2、那么两个栈都存数据呢?  怎么存呢?  试试交替存,每个栈使用一次…  似乎也不行。

        思考到这里就没啥思路了,也没有多大的思考欲望了,感觉再思考下去也只是浪费脑力,事实上,我不太理解
        为啥要用两个栈去实现队列,这么做的意义在哪?

题解

        看了两个题解,发现实现思路还真是好简单,也很巧妙。看出这道题的意义了:很多时候,我们会遇到类似工具不全
        的情况,这种情况看似没有办法完成工作,但很多时候并不是这样的,跳出常理框架,使用有限的工具来完成工作
        是这道题的意义所在。我应该更加努力地去模拟,思考。

        1、汉诺塔思路  stack1:[],  stack2:[]
                假设队列数据:1234,  确保在  stack1  中  是  4321,  这样出栈操作就是出队操作了。
                怎么确保,依然是使用  stack2  协助。
                假设  stack1:[1],  现在需要  将  2  入队
                        则先将  1  挪到  stack2,  等stack清空后,在将  1  挪回来
                        这样  stack1  就变成  stack1:  [2,1]  了
                也就是说,每次要入队,都把数据依次出栈到  stack2,  把新的数据放到栈底,  最后再把数据挪回来。
                天呐,这不就是日常生活中经常出现的操作吗?要把某个东西放到最下面,先把上面的东西依次搬出来。
                但麻烦的也就在这,每次都要搬出来,再搬回去。

class CQueue:

    def __init__(self):
        self.stack1 = []
        self.stack2 = []

    def appendTail(self, value: int) -> None:
        while self.stack1:
            self.stack2.append(self.stack1.pop(-1))
        self.stack1.append(value)
        while self.stack2:
            self.stack1.append(self.stack2.pop(-1))

    def deleteHead(self) -> int:
        return self.stack1.pop(-1) if self.stack1 else -1

        2、优化方案
                不搬回去。  如果  stack1:[1,2,3,4],  搬到  stack2时,就是  [4,3,2,1],  这个时候,
                stack2的出栈顺序已经是正确的出队顺序了,所以如果  stack2  不为空时,可是直接从
                stack2  出栈,为空了再从stack1中搬。。这不又是生活中经常出现的吗?

class CQueue2:
    def __init__(self):
        self.in_stack = []
        self.out_stack = []

    def appendTail(self, value: int) -> None:
        self.in_stack.append(value)

    def deleteHead(self) -> int:
        if not self.out_stack:
            while self.in_stack:
                self.out_stack.append(self.in_stack.pop())
        return self.out_stack.pop() if self.out_stack else -1

原题链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof