返回

巧用双栈,妙解化栈为队,LeetCode面试必备

前端

在软件开发的浩瀚海洋中,数据结构和算法是航海的明灯。掌握这些基本概念至关重要,它们为我们提供了构建强大、高效软件应用程序所需的工具。其中,栈和队列是两个最基本的线性数据结构。

栈遵循“后进先出”(LIFO)原则,就像一叠盘子,后放置的盘子会先被取走。而队列则遵循“先进先出”(FIFO)原则,就像排队等候,先来的人先被服务。

在LeetCode面试题03.04中,我们面临的挑战是使用两个栈来实现一个队列。这道题考察了我们对栈和队列的理解,以及灵活运用数据结构解决问题的能力。

实现MyQueue类

要使用两个栈实现队列,我们需要创建一个MyQueue类。此类包含两个栈:一个用于入队操作(称为inStack),另一个用于出队操作(称为outStack)。

入队操作很简单:只需将新元素推入inStack即可。出队操作则稍微复杂一些。如果outStack为空,我们需要将inStack中的所有元素弹出并压入outStack。然后,我们从outStack中弹出顶元素作为出队元素。

代码实现

class MyQueue {
    private Stack<Integer> inStack;
    private Stack<Integer> outStack;

    public MyQueue() {
        inStack = new Stack<>();
        outStack = new Stack<>();
    }

    public void push(int x) {
        inStack.push(x);
    }

    public int pop() {
        if (outStack.isEmpty()) {
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.pop();
    }

    public int peek() {
        if (outStack.isEmpty()) {
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.peek();
    }

    public boolean empty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }
}

算法分析

该算法的时间复杂度为O(1)。入队操作直接将元素压入inStack,出队操作在必要时将inStack中的元素弹出并压入outStack,然后弹出outStack的顶元素。这两个操作都是常数时间操作。

总结

使用两个栈实现队列的LeetCode面试题03.04是一个很好的练习,可以加深我们对栈和队列的理解。通过巧妙地利用两个栈的特性,我们可以实现一个遵循FIFO原则的队列。这种技术在实际软件开发中很有用,尤其是在需要在内存受限的环境中实现队列时。