题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
条件限制:时间限制:1秒 空间限制:32768K 热度指数:442461
解题前准备:
1. 栈
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。 -----百度百科
如下图(图片来自百度百科)所示:
2. 队列
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。----百度百科
与栈一样,队列也是一种受限的线性表;队列之所以叫队列,就和人排队打饭一样,最先来的最先得到服务。
解题思路:
1. 栈和队列的数据结构其实就是一个黑匣子,别人看不到,这个时候我们只关注每次pop的元素的顺序和队列一样就可以了。栈和队列的区别是:栈是先入后出,队列是先进先出 的顺序,于是每次的push元素的时候都全部堆放在一个栈里,进行pop()操作是我们只需要把栈的n-1个元素全部push到另一个栈,即拿到栈底的元素,然后再把该栈恢复回来即可!思路其实并不难,如果撇开性能而言,按照这种思路就能够利用两个栈来实现队列了,但是如果到此结束了这道题做起来意义并不大,这是算法编程题!并不是简单的实现功能!优化是关键!
2. 试想一下,我们入栈和出栈的顺序是倒过来的,但是把所有元素都push到栈A里,然后再从栈A里pop到栈B,此时栈B的出栈顺序就和队列的出栈顺序一样了!那这样一想,当我有多个连续的pop操作时,比起1中的每次先把A中的n-1个元素先弹出来,才能得到弹栈的元素,不如直接从B中直接弹出,时间复杂度大大降低!当然如果遇到入队和出队操作是相互交替的话,其实时间复杂度也差不多。
3.更高级的优化或者实现方法有待研究......也欢迎将在评论区留下更高级的算法思路!
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
// 将stack2的元素全部压到stack1中,在进行压栈
public void push(int node) {
while (!this.stack2.empty()) {
this.stack1.push(stack2.pop());
}
this.stack1.push(node);
}
public int pop() {
if(this.stack2.empty()) {
while (!this.stack1.empty()) {
this.stack2.push(this.stack1.pop());
}
}
return this.stack2.pop();
}
}