题目
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x)将元素 x 压入栈顶。int pop()移除并返回栈顶元素。int top()返回栈顶元素。boolean empty()如果栈是空的,返回true;否则,返回false。
注意:
- 你只能使用队列的标准操作 —— 也就是
push to back、peek/pop from front、size和is empty这些操作。 - 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
题解
不能使用双端队列的offerLast、pollLast、peekLast等高阶操作
方式一:双队列实现栈
class MyStack {
Deque<Integer> deque1 = new LinkedList<>();
Deque<Integer> deque2 = new LinkedList<>();
public MyStack() {
}
public void push(int x) {
if (deque1.isEmpty()) {
deque2.offer(x);
} else {
deque1.offer(x);
}
}
public int pop() {
// 将非空队列元素移动到空队列,直到非空队列剩一个元素,返回这个元素
// 每次pop之后总有一个队列是空的,保证push操作
if (deque1.isEmpty()) {
while (deque2.size() > 1) {
deque1.offer(deque2.poll());
}
return deque2.poll();
} else {
while (deque1.size() > 1) {
deque2.offer(deque1.poll());
}
return deque1.poll();
}
}
public int top() {
int top = pop();
push(top);
return top;
}
public boolean empty() {
return deque1.isEmpty() && deque2.isEmpty();
}
}
方式二:单队列实现栈
class MyStack {
private Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
}
public int pop() {
int size = queue.size();
// 将队列中除最后一个元素之外的元素依次出队再入队
for (int i = 0; i < size - 1; i++) {
queue.add(queue.poll());
}
// 此时队首元素就是最后入队的元素,即栈顶元素
return queue.poll();
}
public int top() {
int top = pop();
// 再将栈顶元素重新入栈
push(top);
return top;
}
public boolean empty() {
return queue.isEmpty();
}
}
总结
数据结构:栈、队列