LeetCode232:用栈实现队列_java实现(最通俗易懂)
题目描述:
使用栈实现队列的下列操作:
- push(x) – 将一个元素放入队列的尾部。
- pop() – 从队列首部移除元素。
- peek() – 返回队列首部的元素。
- empty() – 返回队列是否为空。
示例:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
说明:
-
你只能使用标准的栈操作 – 也就是只有
push to top
,peek/pop from top
,size
, 和is empty
操作是合法的。 -
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
-
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
思路讲解:
我们带着问题提问分析思考
假设。入栈顺序为 1 -> 2 -> 3 -> 4 -> 5 -> 6(旧栈)
-
只能用栈实现队列,那我们如何保证先进先出?
-
我想到了,只需要将这个栈逆序就行了。 6 -> 5 -> 4 -> 3 -> 2 -> 1(新栈) 那么旧栈为空了
-
好,我们实现这个逆序,只需要将这个栈出栈再压入一个新栈即可,看来我们需要两个栈。
-
如果逆序后,出栈是正确的,不过假如我们入栈还要入新栈还是老栈?
-
肯定是老栈,如果入栈操作的是新栈,那么我们刚才逆序就不争取了,比如我们入栈一个7。
老栈:7
新栈: 6 -> 5 -> 4 -> 3 -> 2 -> 1 ,这里我们逆序过的可以直接取
-
等等,如果新栈一直取,取完了怎么办?
-
那我们再次触发一次逆序,让旧栈的值再次压入新栈中。
-
也就是我们新栈主要负责取,旧栈负责存。
-
可以粗浅理解为,旧栈为生产者,新栈为消费者!
-
秒啊!!!
代码演示:
package com.yang.leetcode.classic;
import java.util.Deque;
import java.util.LinkedList;
public class MyQueue {
// 栈1做数据添加栈(主要入栈)
Deque<Integer> stack1;
// 栈2做逆序好的栈(主要出栈)
Deque<Integer> stack2;
/** Initialize your data structure here. */
public MyQueue() {
stack1 = new LinkedList<>();
stack2 = new LinkedList<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
stack1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
// 先转移栈
peek();
// 直接取出数据
return stack2.removeLast();
}
/** Get the front element. */
public int peek() {
// 栈2为空时,再次将栈1的数据转移到栈2。
if (stack2.isEmpty()){
// 把栈1的数据转移到栈2
while (!stack1.isEmpty()){
stack2.add(stack1.removeLast());
}
}
// 返回栈2的栈顶元素
return stack2.peekLast();
}
/** Returns whether the queue is empty. */
public boolean empty() {
// 如果两个数据栈都没有元素,则返回空
return stack1.isEmpty() && stack2.isEmpty();
}
}
/**
* 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();
*/