面试题7:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
解题思路
由于栈是后进先出的,为了实现队列的先进先出特性,那么两个栈中,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;
}
}