携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
重拾算法-firstday
题目: 使用两个栈实现队列,实现的队列可以支持一般队列的一系列操作,如:队列的先进先出,队尾进,队头出,(push,peek,pop,empty)
实现MyQueue类:
void push(int x)将元素 x 推到队列的末尾int pop()从队列的开头移除并返回元素int peek()返回队列开头的元素boolean empty()如果队列为空,返回 true ;否则,返回 false
标准的栈的操作只有:push to top, peek/pop from top, size, 和 is empty
示例:
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
栈只可以从一头进栈出栈,而队列是一头进一头出,栈其实是一种操作受限的队列,所以将两个栈合在一起形成一个队列。一个负责队列的进,一个负责队列的出。
将一组数据存入第一个栈,再从第一个栈一个一个pop,同时push进第二个栈,完成后,从第二个栈出栈,从而形成队列。
Java版代码如下:
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
public MyQueue() {
stackIn = new Stack<Integer>();
stackOut = new Stack<Integer>();
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
dumpStack();
return stackOut.pop();
}
public int peek() {
dumpStack();
return stackOut.peek();
}
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
public void dumpStack(){
if(!stackOut.isEmpty()) return;
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
代码中,使用两个栈,其中一个用来反转元素的入队的顺序,另一个存储的是元素的最终顺序,从而实现了队列的FIFO特性。
这个题目其实就像两个酒杯相互倒酒,两个酒杯看做是两个栈,把一个杯子里的酒全倒进另一个杯子,然后再倒回来,即可得到最终的顺序。