理论基础
Java中有Stack
类和Queue
类,分别代表栈和队列。
Stack
基于Vector动态数组类实现,是线程安全的,但同步开销较大,在Java中不经常使用。
Queue
有很多实现类
- LinkedList:双向链表,较常用
- PriorityQueue: Object[] 数组来实现小顶堆。
- DelayQueue: PriorityQueue。详细可以查看:DelayQueue 源码分析。
- ArrayDeque: 可扩容动态双向数组。
通常使用双端队列来完成栈的功能。
232.用栈实现队列
已完成
思路:
用栈实现队列,第一次入栈时顺序和队列是反的
再入栈一次,反反则正
两个栈,一个入队列栈,一个出队列栈
入队时把元素压到入队列栈,出队时从出队列栈弹出
若出队列栈为空,则把所有入队列栈的元素压入出队列栈,得到正确的出队顺序
代码
class MyQueue {
// 用栈实现队列,第一次入栈时顺序和队列是反的
// 再入栈一次,反反则正
// 两个栈,一个入队列栈,一个出队列栈
Stack<Integer> inStack;
Stack<Integer> outStack;
// 入队时把元素压到入队列栈,出队时从出队列栈弹出
// 若出队列栈为空,则把所有入队列栈的元素压入出队列栈,得到正确的出队顺序
public MyQueue() {
inStack = new Stack<>();
outStack = new Stack<>();
}
public void push(int x) {
inStack.push(x);
}
public int pop() {
if(!outStack.empty()){
return outStack.pop();
}
while (!inStack.empty()) {
outStack.push(inStack.pop());
}
return outStack.pop();
}
public int peek() {
if(!outStack.empty()){
return outStack.peek();
}
while (!inStack.empty()) {
outStack.push(inStack.pop());
}
return outStack.peek();
}
public boolean empty() {
return inStack.empty()&&outStack.empty();
}
}
225. 用队列实现栈
已完成
思路:
每次出栈其实是把队列最后一个元素出队
此时需要先把队列其他元素保存起来
两个队列,有一个作为备份队列
出栈完毕后,把备份队列的元素再都入队回原队列
代码
class MyStack {
// 每次出栈其实是把队列最后一个元素出队
// 此时需要先把队列其他元素保存起来
// 两个队列,有一个作为备份队列
Queue<Integer> queue;
Queue<Integer> saveQueue;
// 出栈完毕后,把备份队列的元素再都入队回原队列
public MyStack() {
queue = new LinkedList<Integer>();
saveQueue = new LinkedList<Integer>();
}
public void push(int x) {
queue.add(x);
}
public int pop() {
while(queue.size()>1){
saveQueue.add(queue.poll());
}
int res = queue.poll();
while(!saveQueue.isEmpty()){
queue.add(saveQueue.poll());
}
return res;
}
public int top() {
while(queue.size()>1){
saveQueue.add(queue.poll());
}
int res = queue.poll();
saveQueue.add(res);
while(!saveQueue.isEmpty()){
queue.add(saveQueue.poll());
}
return res;
}
public boolean empty() {
return queue.isEmpty();
}
}