[LeetCode] 232. Implement Queue using Stacks

Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (push, peek, pop, and empty).

Implement the MyQueue class:
void push(int x) Pushes element x to the back of the queue.
int pop() Removes the element from the front of the queue and returns it.
int peek() Returns the element at the front of the queue.
boolean empty() Returns true if the queue is empty, false otherwise.

Notes:
You must use only standard operations of a stack, which means only push to top, peek/pop from top, size, and is empty operations are valid.
Depending on your language, the stack may not be supported natively. You may simulate a stack using a list or deque (double-ended queue) as long as you use only a stack's standard operations.

Example 1:
Input
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
Output
[null, null, null, 1, 1, false]

Explanation
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

Constraints:
1 <= x <= 9
At most 100 calls will be made to push, pop, peek, and empty.
All the calls to pop and peek are valid.

Follow-up: Can you implement the queue such that each operation is amortized O(1) time complexity? In other words, performing n operations will take overall O(n) time even if one of those operations may take longer.

用栈模拟队列。

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:
你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-queue-using-stacks
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

同理参考影子题225题。

题干即是题意,用栈实现队列的几个函数,例子,

Example:
MyQueue queue = new MyQueue();

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

思路是需要用到两个栈,用 first 和 second 表示。以下分别解释一下每个函数的实现方式。

push() - 将元素加入队列。这没什么可说的,加入到第一个栈 first 中。时间O(1)

pop() - 弹出队列的首个元素。因为 stack 只会弹出最后一个放入的元素,所以只能通过将第一个 stack 中的元素全部倒入第二个 stack 中,再 pop 第二个 stack 栈顶元素的方式,得到 queue 的首个元素。时间是均摊的 O(n)

peek() - 看一下队列顶端的元素。因为 peek 的功能几乎跟 pop 无异,pop 会弹出首个元素,peek 只是看一下,所以做法跟 pop 几乎相同,也是需要将所有元素都倒入第二个 stack 中再 peek 第二个 stack 的栈顶元素。时间O(1)

empty() - 检测队列是否为空。只要看一下两个 stack 是否都为空即可。时间O(1)

最后分享一个B站非常好的视频讲解,https://www.bilibili.com/video/av86054613/

复杂度

时间 - 同上
空间 - 两个 stack,O(n)

代码

Java实现

class MyQueue {
    Stack<Integer> first;
    Stack<Integer> second;

    public MyQueue() {
        first = new Stack<>();
        second = new Stack<>();
    }

    public void push(int x) {
        first.add(x);
        return;
    }

    public int pop() {
        if (!second.isEmpty()) {
            return second.pop();
        }
        while (!first.isEmpty()) {
            second.add(first.pop());
        }
        return second.pop();
    }

    public int peek() {
        if (!second.isEmpty()) {
            return second.peek();
        }
        while (!first.isEmpty()) {
            second.add(first.pop());
        }
        return second.peek();
    }

    public boolean empty() {
        return first.isEmpty() && second.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();
 */

JavaScript实现

/**
 * Initialize your data structure here.
 */
var MyQueue = function () {
    this.first = [];
    this.second = [];
};

/**
 * Push element x to the back of queue.
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function (x) {
    this.first.push(x);
};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function () {
    // if the second stack is empty, move everything from first to second
    if (!this.second.length) {
        while (this.first.length) {
            this.second.push(this.first.pop());
        }
    }
    return this.second.pop();
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function () {
    // almost same as pop()
    if (!this.second.length) {
        while (this.first.length) {
            this.second.push(this.first.pop());
        }
    }
    return this.second[this.second.length - 1];
};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function () {
    return !this.first.length && !this.second.length;
};

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

相关题目

225. Implement Stack using Queues
232. Implement Queue using Stacks
posted @ 2020-03-04 04:00  CNoodle  阅读(226)  评论(0编辑  收藏  举报