Loading

力扣 - 232. 用栈实现队列.md

题目

232. 用栈实现队列

思路1

  • 即然是使用两个栈,那么一个栈就用来做辅助栈,一个栈用来存元素
  • 我们将栈顶作为队头,将栈底作为队尾,所以如果要push数据的话,先将stack1栈的数据暂时存到stack2辅助栈中,然后将要插入的数据push进入stack1,最后再将stack2的暂存的数据填回到stack1中(注意,回填元素时顺序不能乱)
  • pop时,就是将栈的元素最后一个pop出去,由于我们将队头做为栈顶,所以stack1的pop其实就是出队操作
  • empty:要判断队列是否为空,直接判断stack1是否为空即可
  • 由于栈是基于LinkedList实现的,peek时即查看的是栈顶的元素,所以直接peek就是查看队头的元素

代码

class MyQueue {
    Deque<Integer> mainStack;
    Deque<Integer> helpStack;

    public MyQueue() {
        mainStack = new LinkedList<>();
        helpStack = new LinkedList<>();
    }
    
    public void push(int x) {
        while (!mainStack.isEmpty()) {
            helpStack.push(mainStack.pop());
        }
        mainStack.push(x);
        while (!helpStack.isEmpty()) {
            mainStack.push(helpStack.pop());
        }
    }

    public int pop() {
        return mainStack.pop();
    }
    
    public int peek() {
        return mainStack.peek();
    }
    
    public boolean empty() {
        return mainStack.isEmpty();
    }
}

复杂度分析

  • 时间复杂度:
    • push: \(O(N)\)
    • pop: \(O(1)\)
    • peek: \(O(1)\)
    • empty: \(O(1)\)
  • 空间复杂度:\(O(N)\)

思路2

  • 我们将一个栈用作进栈inStack,另一个栈用作outStack
  • 因为是将inStack的中的所有元素pop出来,pushoutStack中去,则发生位置反转,所以outStack的栈顶元素就是我们队列的队头
  • 出队元素的话只需要从outStack中将栈顶元素pop即可
  • 如果outStack是 空的,就需要将inStack中的所有元素移动到outStack中去
  • 注意:如果outStack中如果不是空的,不能将inStack中的元素移过去,否则顺序被打乱

代码

class MyQueue {
    Deque<Integer> inStack;
    Deque<Integer> outStack;

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

    public void push(int x) {
        // 因为inStack作用就是用于进栈,所以无需其他判断条件
        inStack.push(x);
    }

    public int pop() {
        // 如果outStack是空的,那么就需要将inStack中的元素移动到outStack中去,然后再pop
        if (outStack.isEmpty()) {
            move();
        }
        return outStack.pop();
    }

    public int peek() {
        if (outStack.isEmpty()) {
            move();
        }
        return outStack.peek();
    }

    // 只有两个栈都是空的,就说明队列是空的
    public boolean empty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }

    // 将inStack中的元素移动到outStack中
    public void move() {
        while (!inStack.isEmpty()) {
            outStack.push(inStack.pop());
        }
    }
}

复杂度分析

  • 时间复杂度:
    • push: \(O(1)\)
    • pop: \(O(N)\)
    • peek: \(O(N)\)
    • empty: \(O(1)\)
  • 空间复杂度:\(O(N)\)
posted @ 2020-11-04 21:24  linzeliang  阅读(91)  评论(0)    收藏  举报