LeetCode算法题-Implement Queue Using Stacks(Java实现)

这是悦乐书的第195次更新,第201篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第57题(顺位题号是232)。使用栈实现队列的以下操作。

push(x) - 将元素x推送到队列的后面。

pop() - 从队列前面删除元素。

peek() - 获取前面的元素。

empty() - 返回队列是否为空。

例如:

MyQueue queue = new MyQueue();

queue.push(1);

queue.push(2);

queue.peek(); //返回1

queue.pop(); //返回1

queue.empty(); //返回false

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

队列的特性是先进先出,而栈的特性是先进后去,在使用栈进行队列的出队列和队顶操作时,需要借助另外一个栈来进行反转然后再还原,而入队列的操作还是无需特殊处理。

class MyQueue {

    private Stack<Integer> stack;

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

    /** 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() {
        Stack<Integer> temp = new Stack<Integer>();
        while (!stack.isEmpty()) {
            temp.push(stack.pop());
        }
        int tem = temp.pop();
        while (!temp.isEmpty()) {
            stack.push(temp.pop());
        }
        return tem;
    }

    /** Get the front element. */
    public int peek() {
        Stack<Integer> temp = new Stack<Integer>();
        while (!stack.isEmpty()) {
            temp.push(stack.pop());
        }
        int tem = temp.peek();
        while (!temp.isEmpty()) {
            stack.push(temp.pop());
        }
        return tem;
    }

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


03 第二种解法

此解法和上面的第一种解法正好相反,是在入队列的时候,借助另外一个栈来进行反转操作,而出队列和获取队列顶的操作可以直接使用栈的方法,无需特殊处理。

class MyQueue2 {
    Stack<Integer> stack;

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

    /** Push element x to the back of queue. */
    public void push(int x) {
        Stack<Integer> temp=new Stack<>();
        while(!stack.isEmpty()){
            temp.push(stack.pop());
        }
        temp.push(x);
        while(!temp.isEmpty()){
            stack.push(temp.pop());
        }
    }

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

    /** Get the front element. */
    public int peek() {
        int a = stack.pop();
        stack.push(a);
        return a;
    }

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


04 第三种解法

此解法使用两个栈s1、s2来实现队列的相关操作。

入队列时,如果s2不为空,那么先把s2中的元素pop出来在push进s1,然后才去将当前要插入的数据push进s1。

出队列时,如果s2为空,即此前没有进行出队列操作或者获取队列顶的操作,那么就需要将s1反转,即将s1的元素pop出来,然后push进s2中,此时再返回s2的pop操作即可。如果s2不为空,即说明上一次操作不是入队列,而是出队列或获取队列顶的操作,直接返回s2的pop操作即可。

获取队列顶时,和入队列操作时的判断一致,只不过最后返回s2的peek操作即可。

class MyQueue3 {

    private Stack<Integer> s1;
    private Stack<Integer> s2;

    /** Initialize your data structure here. */
    public MyQueue3() {
        s1 = new Stack<Integer>();
        s2 = new Stack<Integer>();
    }

    /** Push element x to the back of queue. */
    public void push(int x) {
        while(!s2.empty()) {
            s1.push(s2.pop());
        }
        s1.push(x);
    }

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

    /** Get the front element. */
    public int peek() {
        if (s2.empty()) {
            while (!s1.empty()) {
                s2.push(s1.pop());
            }
        }
        return s2.peek();
    }

    /** Returns whether the queue is empty. */
    public boolean empty() {
        return (s1.empty() && s2.empty());
    }
}


05 第四种解法

在入队列时,始终往第一位插入元素,而其他的出队列、获取队列的顶、判空这些操作都可以直接使用栈的方法,而无需重新实现。

class MyQueue4 {

    private Stack<Integer> stack;

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

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

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

    /** Get the front element. */
    public int peek() {
        return stack.peek();
    }

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


06 小结

算法专题目前已连续日更超过一个月,算法题文章57+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

posted @ 2018-12-08 13:54 程序员小川 阅读(...) 评论(...) 编辑 收藏