Stack Coding Problems: 60 Questions with Solutions

60 stack coding problems — 13 easy · 39 medium · 8 hard — with solutions in 13 languages. Plus a step-by-step walkthrough and a 8-day plan.

  • Problems: 60
  • By difficulty: 13 easy · 39 medium · 8 hard
  • Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
  • Cost: Free on every plan; sign in to run and submit

A stack remembers things in the order they can be undone: the last item pushed is the first one back. Matching brackets, evaluating expressions, simplifying a path, finding the next greater element and undoing a sequence of operations all fall out of one push-and-pop loop. The problems here practise seeing the stack in a question that never mentions one.

How stack works, step by step

s{0[1(2)3]4}5(6[7)8]9stack([← topread ')': needs '(', top is '[', mismatchvalid = false
Valid parentheses, with a stack. Example: s = "{[()]}([)]"
  1. A closing bracket must close the most recent opener that is still open: last in, first out, which is exactly a stack. Read the string left to right, push every opener, and on a closer check that the top of the stack is its partner.
  2. '{' at index 0 is an opener, so it is pushed. It waits on the stack until its partner arrives with nothing still open above it.
  3. '[' at index 1 is an opener, so it is pushed on top of '{'. Whatever is on top must be closed first, so '[' now has to be closed before '{' can be.
  4. '(' at index 2 is an opener, so it is pushed on top of '['. Whatever is on top must be closed first, so '(' now has to be closed before '[' can be.
  5. ')' at index 3 needs '(', and the top of the stack is '(', so they match and '(' is popped. '[' is on top again, the next opener waiting to be closed.
  6. ']' at index 4 needs '[', and the top of the stack is '[', so they match and '[' is popped. '{' is on top again, the next opener waiting to be closed.
  7. '}' at index 5 needs '{', and the top of the stack is '{', so they match and '{' is popped. The stack is empty, so "{[()]}" is balanced on its own.
  8. '(' at index 6 is an opener, so it is pushed. It waits on the stack until its partner arrives with nothing still open above it.
  9. '[' at index 7 is an opener, so it is pushed on top of '('. Whatever is on top must be closed first, so '[' now has to be closed before '(' can be.
  10. ')' at index 8 needs '(', but the top is '[': the pairs cross, so the string is invalid and the scan stops. Counting brackets would miss this. One pass, each character pushed and popped at most once: O(n) time and O(n) space.

Stack study plan

14 of the 60 Stack problems (4 easy, 7 medium and 3 hard) over 8 days, about 8 h 10 min in all — the pattern first, then easiest to hardest. After that, the other 46 in the full list below are practice at your own pace. Then move on to Queue.

Day 1

Learn the pattern: read the essentials and step through the walkthrough above, then solve these 3.

Day 2

Medium problems: the same pattern with one twist each. Name the twist before you code.

Day 3

More mediums. Before coding each one, write down what state the pattern keeps and when it changes.

Day 4

More mediums. Before coding each one, write down what state the pattern keeps and when it changes.

Day 5

More mediums. Before coding each one, write down what state the pattern keeps and when it changes.

Day 6

Hard problems: the pattern combined with a second idea. Give each a full attempt before reading the editorial.

Day 7

Another hard one. If it beats you after a real attempt, read the editorial, then solve it again tomorrow from memory.

Day 8

Another hard one. If it beats you after a real attempt, read the editorial, then solve it again tomorrow from memory.

Next topic: Queue

Stack: the essentials

When to reach for it

Nested structure — brackets, tags, encodings like 3[a2[c]]; a symbol that cancels the most recent unmatched one (a backspace, a closing bracket, two colliding asteroids); an expression to evaluate; a recursion you want to run as a loop. The test is whether the item you need next is always the most recent one not yet dealt with.

The pattern

Scan left to right. Push whatever is waiting for a partner; when the current element resolves the top, pop and combine. Whatever is left at the end is unmatched. In reverse Polish notation, numbers are pushed and each operator pops two operands and pushes the result. When the stack must stay in sorted order to answer "next greater" questions, it is a Monotonic Stack.

def is_valid(s):
    pairs = {")": "(", "]": "[", "}": "{"}
    stack = []
    for ch in s:
        if ch in pairs:
            if not stack or stack.pop() != pairs[ch]:
                return False
        else:
            stack.append(ch)
    return not stack

Cost

Each element is pushed and popped at most once: O(n) time and, in the worst case (all openers), O(n) space.

Common mistakes

  • Popping or peeking an empty stack; check before every pop.
  • Declaring success after the scan without checking that the stack is empty.
  • Operand order for - and /: the first pop is the right-hand operand, so pop b, then a, and push a - b.
  • Integer division that must truncate towards zero: Python's // floors, so -7 // 2 is -4; use int(a / b).

Start with

All stack problems

Easy (13)

Medium (39)

Hard (8)

Companies that ask stack problems

Next topic: Queue