Egbert Lin's Blog

“Life is not a race, but a journey to be savoured each step of the way” by Brian Dyson

[LeetCode Road] Implement Stack using Queues - Solution/C++

225. Implement Stack using Queues

Question:

Implement a last in first out (LIFO) stack using only two queues. The implemented stack should support all the functions of a normal queue (push, top, pop, and empty).

Implement the MyStack class:
  • void push(int x) Pushes element x to the top of the stack.
  • int pop() Removes the element on the top of the stack and returns it.
  • int top() Returns the element on the top of the stack.
  • boolean empty() Returns true if the stack is empty, false otherwise.
Notes:
  • You must use only standard operations of a queue, which means only push to back, peek/pop from front, size, and is empty operations are valid.
  • Depending on your language, the queue may not be supported natively. You may simulate a queue using a list or deque (double-ended queue), as long as you use only a queue's standard operations.

Example:

Input
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
Output [null, null, null, 2, 2, false]

Explanation
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // return 2
myStack.pop(); // return 2
myStack.empty(); // return False

Constraints:
  • 1 <= x <= 9
  • At most 100 calls will be made to push, pop, top, and empty.
  • All the calls to pop and top are valid.
  • Follow-up: Can you implement the stack 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. You can use more than two queues.

    Source code

    Version 1

    Idea: It's use one queue method. At first, you must understand queue principle, it follows a particular order to do Enqueue() and Dequeue(), it calls "First in First out", an illustration is shown in below:

    Hence, let's back to push() implementation at this question. Call push() to insert element in queue. Then, use loop to get the front's element and reinsert it into queue, and remove the front's element until the new element is at the front. So, the range of loop is from i = 1 to queue size.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    class MyStack {
    public:
    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
    q.push(x);
    for(int i = 1; i < q.size(); i++){
    q.push(q.front());
    q.pop();
    }
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    int res = q.front();
    q.pop();
    return res;
    }

    /** Get the top element. */
    int top() {
    return q.front();
    }

    /** Returns whether the stack is empty. */
    bool empty() {
    return q.empty();
    }
    private:
    queue<int> q;
    };

    /**
    * Your MyStack object will be instantiated and called as such:
    * MyStack* obj = new MyStack();
    * obj->push(x);
    * int param_2 = obj->pop();
    * int param_3 = obj->top();
    * bool param_4 = obj->empty();
    */

    Version 2

    Idea:
    It is use two queues and avoid using size()
    q2 always stores a new elements. The elements in q1 are given by swap().
    Before doing swap(), it should check wheather q1 is empty or not. If not, you should get the front's element at q1 and insert it into q2, and remove the front's element from q1.
    The demonstration is shown as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    class MyStack {
    public:
    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
    q2.push(x);
    while(!q1.empty()){
    q2.push(q1.front());
    q1.pop();
    }
    q1.swap(q2);
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    int res = q1.front();
    q1.pop();
    return res;
    }

    /** Get the top element. */
    int top() {
    return q1.front();
    }

    /** Returns whether the stack is empty. */
    bool empty() {
    return q1.empty();
    }
    private:
    queue<int> q1;
    queue<int> q2;
    };

    /**
    * Your MyStack object will be instantiated and called as such:
    * MyStack* obj = new MyStack();
    * obj->push(x);
    * int param_2 = obj->pop();
    * int param_3 = obj->top();
    * bool param_4 = obj->empty();
    */