Implement Queue using Stacks

The problem description can be found in LeetCode.

Approach

Suppose that we need to make a lot of push operations. After doing so, the first element that is in the stack (we are forced to use a stack as data structure) is at the bottom. So we cannot directly access it, since there is no stack operation that allows us to do it. In fact, we cannot use any index (as for the requirements).

Now, suppose that we have the same number of pop operations. We know that we must use another stack (as for the requirements), so we can use the other stack to store the values we have to pop. If we pop from the first stack and we push to the second one, magically the actual order is restored, we can start to return the values from the second stack.

Let's take an example:

obj = MyQueue()
obj.push(1)
obj.push(2)
obj.push(3)
obj.push(4)

# `obj.stack_1` would be
#
# | 4 |
# | 3 |
# | 2 |
# | 1 |
# |___|

Now, let's make a single pop operation and move all the elements to the other stack:

obj = MyQueue()
_ = obj.pop()

# `obj.stack_2` would be
#
# | 1 |
# | 2 |
# | 3 |
# | 4 |
# |___|

So if we pop from obj.stack_2 we can get the proper order.

Solution

from typing import List


class MyQueue:
    def __init__(self) -> None:
        self.stack_push: List[int] = []
        self.stack_pop: List[int] = []

    def push(self, x: int) -> None:
        self.stack_push.append(x)

    def pop(self) -> int:
        if self.stack_pop:
            return self.stack_pop.pop()

        self._reorganize_stacks()
        return self.pop()

    def peek(self) -> int:
        if self.stack_pop:
            return self.stack_pop[-1]

        self._reorganize_stacks()
        return self.peek()

    def empty(self) -> bool:
        return not self.stack_push and not self.stack_pop

    def _reorganize_stacks(self) -> None:
        assert not self.stack_pop
        assert self.stack_push

        while self.stack_push:
            self.stack_pop.append(self.stack_push.pop())

Complexity

For the single operation, we would have the following complexities:

  • push:
    • Time:
    • Space:
  • pop:
    • Time:
    • Space:
  • peek:
    • Time:
    • Space:
  • empty:
    • Time:
    • Space: