题目描述(简单难度)

使用栈来实现队列。

思路分析

225 题 是使用队列来实现栈,其中介绍了两种解法,解法一通过一个临时队列来实现 poppeek。解法二只修改 push 。下边的话,我们依旧借助之前的思想来解决这个问题。

解法一

通过一个临时栈,每次 pop 的时候将原来的元素都保存到临时栈中,只剩下最后一个元素,这个元素是第一个加入栈中的,对于队列就是第一个应该弹出的。然后再把原来的元素还原到栈中即可。

peek 的话是同理。

class MyQueue {

    Stack<Integer> stack;

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

    /** 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() {
        int size = stack.size();
        //保存到临时栈中
        Stack<Integer> temp = new Stack<>();
        while (size > 0) {
            temp.push(stack.pop());
            size--;
        }

        int remove = temp.pop();

        //还原
        size = temp.size();
        while (size > 0) {
            stack.push(temp.pop());
            size--;
        }
        return remove;
    }

    /** Get the front element. */
    public int peek() {
        int size = stack.size();
        Stack<Integer> temp = new Stack<>();
        while (size > 0) {
            temp.push(stack.pop());
            size--;
        }
        int top = temp.peek();

        size = temp.size();
        while (size > 0) {
            stack.push(temp.pop());
            size--;
        }
        return top;
    }

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

}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

解法二

我们可以像 225 题 一样,只修改 push 函数。我们只需要每次将新来的元素放到栈底,然后将其他元素还原。

class MyQueue {

    Stack<Integer> stack;

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

    /** Push element x to the back of queue. */
    public void push(int x) {
        Stack<Integer> temp = new Stack<>();
        int size = stack.size();
        //把原来的保存起来
        while (size > 0) {
            temp.push(stack.pop());
            size--;
        }
        //当前元素压到栈底
        stack.push(x);
        size = temp.size();
        //将原来的还原回去
        while (size > 0) {
            stack.push(temp.pop());
            size--;
        }
    }

    /** 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();
    }
}
/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

解法三

上边两种解法都是使用了临时栈,先弹出再还原,每个元素会遍历两次。

参考 这里-amortized-C%2B%2B-Java-Ruby) ,我们使用两个栈,一个栈输入,一个栈输出。当需要查看或者出队的时候,我们就将输入栈元素依次放入到输出栈中,此时的输出栈的输出顺序刚好和队列是相符的。

这样的话,每个元素只会遍历一次了。

可以看一下代码。

class MyQueue {

    Stack<Integer> input = new Stack();
    Stack<Integer> output = new Stack();

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

    public int pop() {
        peek();
        return output.pop();
    }

    public int peek() {
        if (output.empty())
            while (!input.empty())
                output.push(input.pop());
        return output.peek();
    }

    public boolean empty() {
        return input.empty() && output.empty();
    }
}

解法一和解法二的话是完全按照 225 题 的思想,解法三的话,相对解法一和解法二相对要好一些。

results matching ""

    No results matching ""