题目描述:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作( 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(双端队列)来模拟一个栈,只要是标准的栈操作即可。
进阶:
你能否实现每个操作均摊时间复杂度为 O(1)
的队列?换句话说,执行 n
个操作的总时间复杂度为 O(n)
,即使其中一个操作可能花费较长时间。
示例:
输入:
["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 <= x <= 9
- 最多调用
100
次 push
、 pop
、 peek
和 empty
- 假设所有操作都是有效的 (例如,一个空的队列不会调用
pop
或者 peek
操作)
题目分析:
这道题可以使用两个栈来实现一个队列。其中一个栈用作输入栈,当有数据要进入队列时,直接把该数据压入输入栈中。另一个栈用作输出栈,当要获取队列头元素或者队列头元素要出队列时,就获取输出栈的最顶端元素或者把最顶端元素弹出。当然,每次执行获取队列头元素或者队列头元素要出队列操作前,都需要检查输出栈是否为空,如果为空,就需要把输入栈的所有元素先翻转压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序。最后,判断队列是否为空的方法就是直接判断两个栈是否都为空,如果都为空就表明该队列为空。
题解:
执行用时: 0 ms
内存消耗: 36.3 MB
class MyQueue {
// 创建两个栈 一个入栈一个出栈
Stack<Integer> in, out;
public MyQueue() {
in = new Stack<>();
out = new Stack<>();
}
// 添加进队列方法
public void push(int x) {
// 直接把元素压入入栈
in.push(x);
}
// 出队列方法
public int pop() {
// 把入栈的元素翻转进出栈
inToOut();
// 获取出栈最顶端元素值
int x = out.peek();
// 把该元素弹出
out.pop();
// 返回弹出的元素值即队头值
return x;
}
// 获取队列头元素方法
public int peek() {
// 把入栈的元素翻转进出栈
inToOut();
// 返回出栈最顶端元素值
return out.peek();
}
// 判断队列是否为空方法
public boolean empty() {
// 如果入栈和出栈都为空,队列就是空的
return in.empty() && out.empty();
}
// 把入栈的元素翻转进出栈的方法
public void inToOut() {
// 如果出栈为空才进行翻转操作
// 出栈不为空,后进队列的元素直接压进入栈
// 对出栈没有任何影响
if (out.empty()) {
// 把入栈所有元素压入出栈
while (!in.empty()) {
// 获取入栈最顶端元素值
int x = in.peek();
// 把该元素弹出
in.pop();
// 把该元素压入出栈
out.push(x);
}
}
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
题目来源:力扣(LeetCode)