Stacks — LIFO and the problems it solves
Stacks — LIFO for "remember the recent past"
A stack is a Last-In-First-Out queue. In Python it's just a list — append to push, pop() to pop. Both are O(1).
Three classic patterns
1. Matching / balancing
Every open thing (paren, tag, quote) pushes onto the stack. Every closer must match the top of the stack. Balanced brackets, HTML/XML validation, expression evaluation.
2. Undo / history
Every state change pushes a snapshot. Undo pops. Used by editors, transactions, recursive descent parsers.
3. Monotonic stack (the interview trick)
Maintain a stack that stays monotonic (increasing or decreasing). Before you push, pop everything that violates the invariant. Solves in O(n) problems that look O(n²):
- Next greater element
- Largest rectangle in a histogram
- Daily temperatures
- Trapping rain water (harder variant)
Why monotonic stacks work
Each element enters and leaves the stack at most once. Total work is O(n) even though there's a nested loop. Amortized analysis is the interview's favorite gotcha.
Common bugs
- Pop-then-check. Order matters — check the top before popping.
- Empty stack access. Guard
if stack:beforestack[-1]. - Confusing stack of values vs indices. For "find the position of the next greater," store indices, not values.
Try it
- Given a string
s = "a(b(c)d)e", return the parenthesised substrings —["(b(c)d)", "(c)"]. - Implement
daily_temperatures(temps)— for each day, days until a warmer temperature.
3 graded exercises
Write the code, click Check. We’ll tell you exactly what to fix.
- Exercise 1
Write
is_balanced(s)— True when every open bracket has a matching closer in the right order. Use a stack. Test with three inputs and print True, False, True on 3 lines. - Exercise 2
Write
evaluate_rpn(tokens). Tokens are strings — ints or '+', '-', '*', '/'. Use integer floor div//for '/'. Second-popped is left operand. Printevaluate_rpn(['2', '3', '+', '4', '*'])— expected 20. - Exercise 3
Write
next_greater(nums)returning list where each position holds VALUE of next strictly-greater right neighbor, or -1. Use monotonic stack for O(n). Printnext_greater([2, 1, 3, 4, 2, 1])— expected[3, 3, 4, -1, -1, -1].