我们这篇是记录用队列来实现栈:
如果说用栈来实现队列比较巧妙,那用队列来实现栈就算是比较粗暴了。
我们首先看下栈的API
class MyStack {
/** 添加元素到栈顶 */
public void push(int x);
/** 删除栈顶的元素并返回 */
public int pop();
/** 返回栈顶元素 */
public int top();
/** 判断栈是否为空 */
public boolean empty();
}
先看 push 方法,是直接将元素加入队列,同时记录队尾元素,因为队尾的元素相当于栈顶的元素,所以如果要 top 查看栈顶元素的话可以直接返回记录的值。
class MyStack {
Queue‹Integer› q = new LinkedList‹›();
int top = 0;
/** 添加元素到栈顶 */
public void push(int x) {
// x 是队列的队尾,是栈的栈顶
q.offer(x);
top_elem = x;
}
/** 返回栈顶元素 */
public int top() {
return top;
}
}
我们底层的数据结构是先进先出的队列,所以每次 pop 只能从对头取元素,
但是栈是后进先出,也就是说 pop 要从队尾取元素。
解决方案就是:把队列前边的元素都取出来,再加入队尾,让之前的队尾元素排到队头,这样就可以当一个栈来使用了。
Leetcode 上题目 225 是用队列实现栈的例子。
解法如下:
class MyStack {
private Queue<Integer> q;
int top;//记录栈顶元素,即队尾的元素
public MyStack() {
q = new LinkedList<>();
}
public void push(int x) {
q.offer(x);
top = x;//x是队尾的元素,是栈顶
}
public int pop() {
int size = q.size();
while(size >2){
q.offer(q.poll());
size--;
}
//原来的队尾元素被提到队头并删除了,但是 top 变量没有更新
//记录新的队尾元素,要就被删除了
top = q.peek();
q.offer(q.poll());
return q.poll();
}
public int top() {
return top;
}
public boolean empty() {
return q.isEmpty();
}
}