请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x)将元素 x 压入栈顶。int pop()移除并返回栈顶元素。int top()返回栈顶元素。boolean empty()如果栈是空的,返回true;否则,返回false。
注意:
- 你只能使用队列的标准操作 —— 也就是
push to back、peek/pop from front、size和is empty这些操作。 - 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
思路:我们已知队列和栈所存入数据的顺序是相反的。如果要想将对队列的操作变为对栈的操作,那么可能得将其翻转。
定义两个队列queue1和queue2,首先判断队列1 queue1 是否为空,如果不为空,则将queue1中的数全部存入queue2中,当queue1为空时将新要加入的数加入queue中,然后再queue2中的数返回queue1中,这样就能保证每一次加入的数都是存在的了队列的开头。 例如存入1和2:
可以看到,最后的队列发生了翻转。
代码如下:
其中存数用add方法,去除头部用poll方法,判断是否为空用isEmpty()方法,这是用LinkedList<>()来实现队列时所用的方法。
另一种思路如下:
在push操作时不改变队列的顺序,按顺序输入,在进行pop操作时,将第一个队列中的数移动到队列二中,仅剩下最后一个数,然后进行poll操作,得到堆栈的第一个数,然后将第二个队列的数返回第一个队列,这样刚好队列的最后一个数就没有了,并保留了原队列。
在进行peek操作时,同样将队列一中的数移动到队列二中,剩下最后一个元素,然后进行peek操作,不同的是,在进行完peek操作后,队列一中的最后一个数并不会被清除,这时需要将队列一中的最后一个数输入到队列二中,然后再讲队列二作为一个整体返回队列一中。
代码如下: