题目
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列的支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks
题解
思路一:使用两个栈,主栈用于push/pop,辅助栈用于翻转
对于push(x)
- 先将主栈的元素全部移到辅助栈
- 将x压入主栈
- 将辅助站的元素放回
对于pop(x),则直接从主栈弹出
java代码
class MyQueue {
Deque<Integer> stackFst;
Deque<Integer> stackSnd;
/** Initialize your data structure here. */
public MyQueue() {
stackFst = new LinkedList<Integer>();
stackSnd = new LinkedList<Integer>();
}
/** Push element x to the back of queue. */
public void push(int x) {
// 先将所有元素放入另外一个栈
while (!stackFst.isEmpty()) {
stackSnd.push(stackFst.pop());
}
stackFst.push(x);
// 先将所有元素放入放回
while (!stackSnd.isEmpty()) {
stackFst.push(stackSnd.pop());
}
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if (empty()) {
return -1;
}
return stackFst.pop();
}
/** Get the front element. */
public int peek() {
if (empty()) {
return -1;
}
return stackFst.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stackFst.isEmpty();
}
}
思路2:使用两个栈,一个栈用于push,一个栈用于pop
优化之处:
- 利用FIFO顺序的特性,每次pop时候,将push栈的元素转移到pop栈的时间复杂度平均是:pop的数量/push的数量,最坏是O(1)
- 分开存放减少了移动元素的次数
class MyQueue {
Deque<Integer> stackFst;
Deque<Integer> stackSnd;
int front;
/** Initialize your data structure here. */
public MyQueue() {
stackFst = new LinkedList<Integer>();
stackSnd = new LinkedList<Integer>();
}
/** Push element x to the back of queue. */
public void push(int x) {
// 存放栈顶元素,用于peek
if (stackFst.isEmpty()) {
front = x;
}
stackFst.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if (empty()) {
return -1;
}
if (stackSnd.isEmpty()) {
while (!stackFst.isEmpty()) {
stackSnd.push(stackFst.pop());
}
}
return stackSnd.pop();
}
/** Get the front element. */
public int peek() {
// 要么是push栈底部,要么是pop栈顶部
if (empty()) {
return -1;
}
if (stackSnd.isEmpty()) {
return front;
}
return stackSnd.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stackFst.isEmpty() && stackSnd.isEmpty();
}
}