前言
提示:以下是本篇文章正文内容,编程语言为Java
一、题目描述
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、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 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例 1:
输入:
["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
链接:用栈实现队列
二、解题思路
队列的特性是先进先出,栈的特性先进后出。我们可以用两个栈来模拟队列。栈1
专门用来模拟入队, 栈2
专门用来模拟出队。
1) 当入队时,我们直接将元素插入 栈1
即可。
2) 当出队时,我们将 栈1
的元素依次全部弹出,并插入 栈2
,然后对 栈2
执行出栈即可。
3) 当队列执行 peek()
时,我们将 栈1
的元素依次全部弹出,并依次插入 栈2
,然后对 栈2
执行 peek()
即可。
4) 当队列执行 empty()
时,我们只需判断两个栈是否都为空。
三、示例代码
class MyQueue {
private Deque<Integer> st1;
private Deque<Integer> st2;
public MyQueue() {
st1=new LinkedList<>();
st2=new LinkedList<>();
}
public void push(int x) {
st1.push(x);
}
public int pop() {
if(st2.isEmpty()){
while(!st1.isEmpty()){
st2.push(st1.pop());
}
}
return st2.pop();
}
public int peek() {
if(st2.isEmpty()){
while(!st1.isEmpty()){
st2.push(st1.pop());
}
}
return st2.peek();
}
public boolean empty() {
return st1.isEmpty() && st2.isEmpty();
}
}
总结
队列是一种先进先出的容器,栈是一种先进后出的容器。在Java中,我们用双端队列来初始化栈或队列:
Deque<T> s/q = new LinkedList<>()
Deque
封装了栈和队列的常用函数:
1)队列
函数 | 描述 |
---|---|
offer(e) | 入队 |
poll() | 出队 |
peek() | 获取队首元素 |
isEmpty() | 判断队列是否为空 |
2)栈
函数 | 描述 |
---|---|
push(e) | 入栈 |
pop() | 出栈 |
peek() | 获取栈顶元素 |
isEmpty() | 判断栈是否为空 |