问题描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
解法1
入队的时候只push到栈1,而出队的时候先将栈1中的元素全部倒入栈2,然后弹出栈2顶端元素,并将剩下的栈2全部元素弹回栈1。
import java.util.Stack;
/**
* 思路:第一个栈作为压入栈,第二个栈作为弹出栈,压入的时候只压入第一个栈,
* 弹出的时候只从第二个栈弹出,
* 弹出到第二个栈的时候,先把栈1全部弹出到栈2,然后弹出栈2顶的元素,然后再弹回去栈1
*/
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()) {
throw new RuntimeException("queue is empty");
}
// 将栈1倒入栈2
while(!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
// 弹出栈2栈顶元素
int popData = stack2.pop();
// 将栈2倒回栈1
while(!stack2.isEmpty()) {
stack1.push(stack2.pop());
}
return popData;
}
}
入队的时间复杂度为O(1),出队时,需要将栈1倒入栈2,并将栈2倒回栈1,时间复杂度为O(n)。这种方法实现出队效率一般。
解法2
上面的做法是每次出队的时候,都要将栈1的元素放到栈2中,并且之后还要放回栈1,这样倒来倒去似乎效率有点低。
优化的思路是:每次出队的时候将栈1中元素全部放入栈2后,栈2的元素还可以用于每次出队操作,而不必每次出队都要从栈1中取,只有当栈2为空的时候,才去栈1中取。需要注意的是,每次从栈1取元素的时候,都要取出栈1中全部元素到栈2,不然会出现栈2中有些元素已经出栈但是还在栈1中存在。
import java.util.Stack;
/**
* 思路:
* 1. 第一个栈作为压入栈,第二个栈作为弹出栈,
* 2. 压入的时候只压入第一个栈,弹出的时候只从第二个栈弹出,
* 3. 弹出的时候如果栈2为空,就将栈1全部倒入,如果栈2不为空,就不需要去栈1取
* 4. 最后弹出栈2栈顶元素
*/
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.isEmpty() && stack1.isEmpty()) {
throw new RuntimeException("queue is empty");
}
// 只有当栈2为空的时候才从栈1中取出数据
if(stack2.isEmpty()) {
while(!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
// 弹出栈2,栈顶的元素
return stack2.pop();
}
}
网友评论