232:用栈实现队列

问题描述

使用栈实现队列的下列操作:

  • push(x) – 将一个元素放入队列的尾部。
  • pop() – 从队列首部移除元素。
  • peek() – 返回队列首部的元素。
  • empty() – 返回队列是否为空。

示例

MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);  
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empty操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

思路

设置两个栈,一个作为主栈,一个作为辅助栈。模拟队列时,入队时直接入主栈。 获取队头或者是出队时,先将主栈中所有东西倒入辅助栈,然后把栈底元素记录下来或者弹出,再把辅助栈中的东西全部倒入主栈。
总而言之就是,辅助栈中不存储东西,只是临时存储,只是为了弹出或者是取队头而用的一个临时存储区。(方法一)

这个方法花费了1ms。有点慢。想了想怎么优化。咦,卧槽。把主栈的东西倒到辅助栈的时候,我何必再把它倒回去呢?因为此时辅助栈就变成了一个"队列"了啊。先"入队"的元素在辅助栈的栈顶了。
所以,改进算法:辅助栈为空时,把主栈的所有东西都倒到辅助栈中。在出队或者是取队头时,如果辅助栈不为空,证明这个"假队列"还有效,直接弹栈。如果为空,则把主栈的所有东西都倒进来。
那么,入队的时候是入到主栈还是辅助栈呢? 当然是入到主栈了。 在这个结构中,主栈的栈顶永远是最后入队的元素,辅助栈的栈顶永远是最先入队的元素。
那么,判空呢? 两个栈都为空才算队空。(方法二)

方法一

Java版

class MyQueue {
    Stack<Integer> main = new Stack<>();
    Stack<Integer> aid = new Stack<>();
    /** Initialize your data structure here. */
    public MyQueue() {

    }

    /** Push element x to the back of queue. */
    public void push(int x) {
        main.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        while(main.size() > 1){
            aid.push(main.pop());
        }
        int res = main.pop();
        while(!aid.isEmpty()){
            main.push(aid.pop());
        }
        return res;
    }

    /** Get the front element. */
    public int peek() {
        while(main.size() > 1){
            aid.push(main.pop());
        }
        int res = main.peek();
        while(!aid.isEmpty()){
            main.push(aid.pop());
        }
        return res;
    }

    /** Returns whether the queue is empty. */
    public boolean empty() {
        return main.isEmpty();
    }
}

方法二

Java版

class MyQueue {
    Stack<Integer> stack = new Stack<>();
    Stack<Integer> queue = new Stack<>();
    /** Initialize your data structure here. */
    public MyQueue() {
        
    }

    /** Push element x to the back of queue. */
    public void push(int x) {
        stack.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        if(queue.isEmpty()){
            while(!stack.isEmpty()){
                queue.push(stack.pop());
            }
        }
        return queue.pop();
    }

    /** Get the front element. */
    public int peek() {
        if(queue.isEmpty()){
            while(!stack.isEmpty()){
                queue.push(stack.pop());
            }
        }
        return queue.peek();
    }

    /** Returns whether the queue is empty. */
    public boolean empty() {
        return queue.isEmpty()&&stack.isEmpty();
    }
}
发布了396 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41687289/article/details/104825125