1. Using Two Queues

class MyStack:

    def __init__(self):
        self.q1 = deque()
        self.q2 = deque()

    def push(self, x: int) -> None:
        self.q2.append(x)
        while self.q1:
            self.q2.append(self.q1.popleft())

        self.q1, self.q2 = self.q2, self.q1

    def pop(self) -> int:
        return self.q1.popleft()

    def top(self) -> int:
        return self.q1[0]

    def empty(self) -> bool:
        return len(self.q1) == 0

Time & Space Complexity

  • Time complexity:
    • O(1)O(1) time for initialization.
    • O(n)O(n) time for each push()push() function call.
    • O(1)O(1) time for each pop()pop() function call.
  • Space complexity: O(n)O(n)

2. Using One Queue

class MyStack:

    def __init__(self):
        self.q = deque()

    def push(self, x: int) -> None:
        self.q.append(x)
        for _ in range(len(self.q) - 1):
            self.q.append(self.q.popleft())

    def pop(self) -> int:
        return self.q.popleft()

    def top(self) -> int:
        return self.q[0]

    def empty(self) -> bool:
        return len(self.q) == 0

Time & Space Complexity

  • Time complexity:
    • O(1)O(1) time for initialization.
    • O(n)O(n) time for each push()push() function call.
    • O(1)O(1) time for each pop()pop() function call.
  • Space complexity: O(n)O(n)

3. Queue Of Queues

class MyStack:

    def __init__(self):
        self.q = None

    def push(self, x: int) -> None:
        self.q = deque([x, self.q])

    def pop(self) -> int:
        top = self.q.popleft()
        self.q = self.q.popleft()
        return top

    def top(self) -> int:
        return self.q[0]

    def empty(self) -> bool:
        return not self.q

Time & Space Complexity

  • Time complexity:
    • O(1)O(1) time for initialization.
    • O(1)O(1) time for each push()push() function call.
    • O(1)O(1) time for each pop()pop() function call.
  • Space complexity: O(n)O(n)