题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:
用两个先进后出的栈来实现一个先进先出的队列。显然,出栈顺序和我们所求的出队列的顺序是相反的。
如果把第一个栈中的元素压入第二个栈,此时经历了压入——弹出——再压入,此时如果再弹出,则和我们所需要的队列 的弹出顺序是一致的。
当有数据要入队的时候,我们就让它压入stack1,要进行pop操作的时候,我们就把stack1里面的数据全部压入stack2中,
然后对stack进行一次pop操作就可以了,因为此时stack的栈顶就相当于队列的最先进来的数据
当然在pop操作里需要先判断两个栈是否都为空,而且当stack2不为空的话就可以直接进行stack2.pop(),
stack2为空但是stack1不为空在进行上面的操作)。
更清晰的思路参考这个博客:https://www.cnblogs.com/MrListening/p/5697459.html,画图也画的清晰明了。
代码1:
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack2.size()<=0){//stack2为空
while(stack1.size()>0){//stack1不为空
stack2.push(stack1.pop());
}
}
if(stack2.isEmpty()){
try{
throw new Exception("queue is empty!");
}catch (Exception e) {
// TODO: handle exception
}
}
Integer head=stack2.pop();
return head;
}
}
代码2:
与代码1不同之处就是pop的判断方式有所不同,但是思想都是一致的,关键之处在于下面这句话:
当然在pop操作里需要先判断两个栈是否都为空,而且当stack2不为空的话就可以直接进行stack2.pop(),
stack2为空但是stack1不为空在进行上面的操作)。
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack1.empty()&&stack2.empty()){
try {
throw new Exception("queue is empty");
} catch (Exception e) {
// TODO: handle exception
}
}
if(stack2.empty()){
while(!stack1.empty()){
stack2.push(stack1.pop());
}
}
Integer head=stack2.pop();
return head;
}
}
题目衍生:
因为两个栈实现队列和两个队列实现栈的题目经常会一起被问到,所以也实现了一下用两个队列实现一个栈的方法。主要思路参考这个博客:
https://blog.csdn.net/sheepmu/article/details/38428205
思路:
压入栈:直接用队列的add()方法(相当于以前的addLast,添加新的元素到队尾的方法),不需要什么特殊的判断。
弹出栈:所有元素a,b,c进队列q1,我们的目的是栈,也就是最先c。而队是从队头出的。所以先把a,b出q1并放入q2,此时q1中的元素c跑到了队头,让c出q1.此时q1已经为空,下一个要出队的是b,因此把a从q2中出队并送入q1,此时q2中的b跑到了队头,出b。
总结为:把非空队列的前n-1个元素压入空队列,剩下最后一个(第n个元素)出队...最后总有一个队列为空 。
代码见下:
class TwoQueueToSatck {
Queue<Integer> queue1 = new ArrayDeque<>();
Queue<Integer> queue2 = new ArrayDeque<>();
//入栈
public void push(int value){
queue1.add(value);
}
//出栈
public int pop(){
//必须是非空才可以出栈
if(queue1.size()+queue2.size()!=0){
//q1不为空,将q1的前n-1个元素移动到q2中
if(!queue1.isEmpty()){
putN_1ToAnother();
return queue1.remove();
}else{
//q2不为空,将q2的前n-1个元素移动到q1中
putN_1ToAnother();
return queue2.remove();
}
}
else{
System.out.println("栈为空,不能出栈");
return -1;
}
}
private void putN_1ToAnother() {
//从非空队列中出前n-1个到空队列(队列总是一空一非空)
// TODO Auto-generated method stub
if(!queue1.isEmpty()){
while(queue1.size()>1){
queue2.add(queue1.remove());
}
}else{
if(!queue2.isEmpty()){
while(queue2.size()>1){
queue1.add(queue2.remove());
}
}
}
}