Categories:

Tags:



Problem

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.

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.

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.

Solution

The problem Implement Queue using Stacks can be solved using 2 stacks, one to hold pushed value and the other to simulate a queue. By moving elements from a cache only when peek or pop operation is performed when the other stack is empty, it is possible to reduce achieve amortized O(1) time complexity.

Implementation

class MyQueue
{
  private:
    stack<int> _cache;
    stack<int> _queue;

  public:
    MyQueue() {}

    void push(int x) { _cache.push(x); }
    int pop()
    {
        int ret = peek();
        _queue.pop();
        return ret;
    }

    int peek()
    {
        if (_queue.empty())
            while (!_cache.empty())
            {
                _queue.push(_cache.top());
                _cache.pop();
            }

        return _queue.top();
    }

    bool empty() { return _cache.empty() && _queue.empty(); }
};

/**
 * 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();
 * bool param_4 = obj->empty();
 */