【剑指offer-04】用两个栈实现一个队列

问题描述

用两个栈来实现一个队列,完成队列的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中每次都要取出全部元素到栈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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值