题目要求
Implement the following operations of a queue using stacks.
push(x) -- Push element x to the back of queue.
pop() -- Removes the element from in front of queue.
peek() -- Get the front element.
empty() -- Return whether the queue is empty.
Notes:
You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid.
Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).
使用队列来模拟实现一个栈。
栈是指先进后出的数据结构,而队列则是先进先出的数据结构。
假设我们分别往栈和队列中顺序输入[1,2,3],那么栈的输出是[3,2,1],而队列的输出的[1,2,3]。
队列的API包括在队列尾插入数据,输出队列头的数据,查看队列的长度,队列是否为空。
那么我们现在看一下如何通过队列来实现栈的操作。
方法一:两个队列
当插入数据中时,固定往非空的那个队列插入数据。(如果两个队列的值都为空,那么就任选一个队列插入即可)。当想要获得栈顶数据或者执行栈的pop操作时,那么就将队列中的值逐个输出到另一个队列中,并输出原队列中最后一个元素的值。
下面用图形展示一下:
1.向数据结构中插入1,因为此时两个队列总都为空,因此任选一个队列插入
2.向数据结构中插入2和3,因为此时队列一非空,因此插入队列一
3.模拟pop操作,这是需要将队列一的内容输出再输入到队列二中并丢弃队列1中最后一个元素,即为3
4.模拟top操作,类似于pop,将非空队列的内容逐个转移至空队列,并记录最后的一个元素返回,即为2
代码如下:
public class Stack {
LinkedList queue1 = new LinkedList();
LinkedList queue2 = new LinkedList();
/** Push element x onto stack. */
public void push(int x) {
if(queue1.isEmpty()){
queue2.offer(x);
}else{
queue1.offer(x);
}
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
int top = 0;
if(queue1.isEmpty()){
while(queue2.size() > 1){
top = queue2.poll();
queue1.offer(top);
}
top = queue2.poll();
}else{
while(queue1.size() > 1){
top = queue1.poll();
queue2.offer(top);
}
top = queue1.poll();
}
return top;
}
/** Get the top element. */
public int top() {
int top = 0;
if(queue1.isEmpty()){
while(!queue2.isEmpty()){
top = queue2.poll();
queue1.offer(top);
}
}else{
while(!queue1.isEmpty()){
top = queue1.poll();
queue2.offer(top);
}
}
return top;
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue1.isEmpty() && queue2.isEmpty();
}
}
思路二:单个队列模拟栈
思路一使用两个队列从而确保值从队列中丢出的过程不会丢失。但是其实一个队列已经足以来模拟栈。我们只需要在每一次往队列中输入数据时,确保当前队列中的输出顺序和栈相同即可。同样我们使用图片来模拟一下过程。
1.输入1,这时队列为空,将1正常输入
2.输入2,这时为了确保队列的输出顺序和栈相同,我需要将1输出并重新输入,这时可以把1看成一个新输入的值,所以将在2之后输出
3.输入3,同上一步,在输入新加入的值后,将余下的值输出后重新输入一遍
其实队列的最大特点就是可以维护原来的输入顺序,因此每次输出再重新输入的数据之间的顺序不会受到影响。
4.pop和push只需要输出或者读取队首的值即可
class MyStack {
/** Initialize your data structure here. */
Queue queue;
public MyStack() {
queue = new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
int size = queue.size();
queue.offer(x);
while (size-- > 0) {
queue.offer(queue.poll());
}
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue.poll();
}
/** Get the top element. */
public int top() {
return queue.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
}
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~