剑指Offer题目7:用两个栈来实现一个队列(Java)

1,555 阅读2分钟

面试题7:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

牛客网 OJ:用两个栈实现队列

解题思路

由于栈是后进先出的,为了实现队列的先进先出特性,那么两个栈中,stack1 用来实现 push。当该仿真队列

不断执行 push 操作时,元素一个个被压到栈中,此时的顺序是最先的元素在栈的最底部,顺序和队列元素相反。

当要弹出元素时,我们期望将 stack1 的数据逆序输出去,即从栈底开始依次弹出,此时就得借助 stack2 了。

执行仿真队列的 pop 操作时,将 stack1 的元素全部 pop 出来并压入 stack2,此时 stack2 就变成栈底
是最后 push 进队列(最后 push 到 stack1)、栈顶是最先 push 到队列(最先 push 到 stack1)的元素
顺序,对 stack2 直接 pop 就是期望的队列元素。

间接实现了队列的先进先出特性。 

代码实现

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.isEmpty() && stack2.isEmpty()) {
            throw new RuntimeException("Queue is empty!");
        }
        if(!stack2.isEmpty()) {
            return stack2.pop();
        }
        while(!stack1.isEmpty()) {
            stack2.push(stack1.pop());
        }
        return stack2.pop();
    }
}

总结

栈和队列这两种数据结构可以互相用来实现对方,但必须多出同类型的一个辅助数据结构才行。

扩展:两个队列实现栈

思路

每次 push 进 Queue1, 都是先进先出的序列,而 pop 时要求实现后进先出,由于队列只能最先进的从队列头最先
弹出,此时,可以将 Queue1 的元素,全部 pop 出来,通过一个变量 element 来暂存 Queue1 中的最后一个元
素,在这个过程中,将弹出的元素 push 到 Queue2(除 Queue1 最后一个元素),返回的 element 就是最后 push
到队列的值,相当于栈顶元素,间接实现栈的后进先出特性。

如果此时要继续 pop 出仿真栈的下一个元素,则模仿上一步,将 Queue2 所有元素,除了最后一个元素都 pop 出来,
并 push 进 Queue1, 这个过程中同样通过 element 这个变量来保存 Queue2 的最后一个元素,返回该元素即栈
顶元素。

注意:每次 pop 都最终保证一个 Queue 为空。
如此交替装元素,一个作为发射枪发射子弹,另一个作为容器装这个发射枪的发出的子弹。

代码实现

import java.util.Queue;

public class Solution {
    
    Queue<Integer> queue1 = new Queue<Integer>();
    Queue<Integer> queue2 = new Queue<Integer>();
    
    public void push(int node) {
        if(queue1.size() != 0) {
            queue1.add(node);
        } else if(queue2.size() != 0) {
            queue2.add(node);
        } else {
            queue1.add(node);
        }
    }
    
    public int pop()() {
       if(queue1..size() == 0 && queue2..size() == 0) {
           return new RuntimeException("Stack is empty!");
       }
        int element;
       if(queue1.size() != 0) {
           while(queue1.size() > 0){
               element = queue1.poll();
               if(queue1.size() != 0) {
                   queue2.add(element);
               }
           }
       } else {
           while(queue2.size() > 0) {
               element = queue2.poll();
               if(queue2.size() != 0) {
                   queue1.add(element);
               }
           }
       }
        return element;
    }
}