34 Push and pop 5s

Stack push/pop is the foundation for all LIFO operations: DFS, undo, and expression parsing.

stack = []
stack.append(x)
stack.pop()
35 Check balanced parens 15s

Bracket matching is the classic stack application. Must be instant for interview warm-ups.

match = {'(': ')', '[': ']', '{': '}'}
stack = []
for c in s:
    if c in match:
        stack.append(match[c])
    elif not stack or stack.pop() != c:
        return False
return not stack
36 Min stack push 10s

Maintaining a parallel min stack gives O(1) getMin. Classic design problem.

self.stack.append(val)
self.min_stack.append(
    min(val, self.min_stack[-1] if self.min_stack else val)
)
37 Evaluate postfix token 15s

Stack-based expression evaluation is the foundation for calculator and RPN problems.

for tok in tokens:
    if tok.lstrip('-').isdigit():
        stack.append(int(tok))
    else:
        b, a = stack.pop(), stack.pop()
        if tok == '+': stack.append(a + b)
        elif tok == '-': stack.append(a - b)
        elif tok == '*': stack.append(a * b)
        elif tok == '/': stack.append(int(a / b))
38 Monotonic stack template 10s

Monotonic stacks find next-greater/smaller elements in O(n). Key for histogram and temperature problems.

stack = []
for x in a:
    while stack and stack[-1] >= x:
        stack.pop()
    stack.append(x)
39 Next greater element 15s

Next-greater-element uses a decreasing stack. Shows up in stock span and temperature problems.

result = [-1] * len(a)
stack = []
for i in range(len(a) - 1, -1, -1):
    while stack and stack[-1] <= a[i]:
        stack.pop()
    if stack:
        result[i] = stack[-1]
    stack.append(a[i])
40 Stack to reverse 10s

Using a stack to reverse order is the intuition behind reversing linked lists and strings.

stack = []
for x in a:
    stack.append(x)
reversed_a = []
while stack:
    reversed_a.append(stack.pop())
134 Eval RPN with stack 10s

Stack-based evaluation pops two operands per operator. Handles all four arithmetic ops.

st = []
for t in tokens:
    if t in '+-*/':
        b, a = st.pop(), st.pop()
        st.append(int(eval(f'{a}{t}{b}')))
    else:
        st.append(int(t))
135 Daily temperatures monotonic stack 15s

Decreasing stack resolves waiting days when a warmer temperature arrives.

res = [0] * len(t)
st = []
for i, v in enumerate(t):
    while st and t[st[-1]] < v:
        j = st.pop()
        res[j] = i - j
    st.append(i)
243 Stack vs queue: LIFO vs FIFO decision 15s

Stack = most recent first (nesting, matching). Queue = oldest first (BFS, scheduling). Deque = both ends.

STACK (LIFO) vs QUEUE (FIFO)
────────────────────────────
STACK — Last In, First Out:
  "most recent" / "nested" / "matching"
  □ Parentheses matching
  □ Undo/redo
  □ DFS traversal (explicit stack)
  □ Monotonic stack (next greater element)
  □ Expression evaluation
  □ Call stack simulation

QUEUE — First In, First Out:
  "earliest" / "level-by-level" / "waiting line"
  □ BFS traversal (shortest path)
  □ Level-order tree traversal
  □ Task scheduling (FIFO order)
  □ Sliding window max (deque)
  □ Rate limiting (timestamp queue)

DEQUE — both ends:
  □ Sliding window maximum
  □ BFS optimizations
  □ Palindrome check

PRIORITY QUEUE (heap):
  □ "Next best" / "top K" / "median"
  □ Dijkstra, merge K sorted lists
249 When to use monotonic stack 15s

Monotonic stack finds nearest greater/smaller in O(n). The key insight: popping means we found the answer for that element.

WHEN TO USE MONOTONIC STACK
───────────────────────────
SIGNAL PHRASES:
  "next greater/smaller element"
  "previous greater/smaller element"
  "span" / "days until warmer"
  "largest rectangle in histogram"
  "stock span problem"

PATTERN:
  stack = []  # stores indices, monotonic order
  for i in range(n):
      while stack and a[stack[-1]] < a[i]:  # or >
          j = stack.pop()
          # a[j]'s next greater is a[i]
          # a[j]'s previous greater is stack[-1] (if exists)
      stack.append(i)

MONOTONIC INCREASING STACK: finds next smaller
MONOTONIC DECREASING STACK: finds next greater

WHEN NOT monotonic stack:
  × Sliding window max → use deque (not just stack)
  × Need both prev AND next → two passes or one pass
  × No "nearest" relationship → wrong tool

COMPLEXITY: O(n) — each element pushed and popped once
272 Evaluate Reverse Polish Notation 15s

RPN evaluation: numbers push, operators pop two and push result. Note: pop order is b, a (right operand first).

stack = []
for tok in tokens:
    if tok in '+-*/':
        b, a = stack.pop(), stack.pop()
        if tok == '+': stack.append(a + b)
        elif tok == '-': stack.append(a - b)
        elif tok == '*': stack.append(a * b)
        else: stack.append(int(a / b))
    else:
        stack.append(int(tok))