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