Reading a Problem: Choosing the Right Tool
A repeatable triage for turning a wall of prose into 'oh, this is a monotonic stack'.
- Run a fixed 7-step triage on any problem instead of pattern-matching from memory
- Read input constraints and infer the intended time complexity before writing code
- Use the 'shape of the input' and 'what am I optimising' heuristics to shortlist structures
- Always start from a brute force, then locate the wasted work and name the structure that removes it
The actual gap
You already know what a hash map, a heap, and a BFS are. You've drawn the recursion tree. The thing that keeps sending you back to square one every interview season isn't the structures — it's the translation step: a wall of prose comes in, and you can't see which structure it's quietly describing, or you see it but freeze when turning it into Go.
Both halves are trainable. This module is the translation half. The rest of the course drills the coding half, one pattern at a time, with the same triage applied every time so it becomes muscle memory.
The 7-step triage
Do these in order, every time, even when you think you know the answer. The steps you're tempted to skip are the ones that catch you.
- 1. Read it twice. Restate the problem in one sentence, out loud.
- 2. Nail the I/O contract: types, ranges, edge inputs.
- 3. Read the constraints — they tell you the target complexity.
- 4. Name the brute force and its cost.
- 5. Find the wasted work.
- 6. Match the waste to a structure.
- 7. Sanity-check complexity, then code.
step 1: Read it twice. Restate the problem in one sentence, out loud.
Step 3 in depth: constraints → complexity
Competitive-style problems tell you the input size on purpose. Assume the machine does ~108–109 simple operations per second, then read the size backwards to the intended complexity:
| Input size n | Intended complexity | What that rules in |
|---|---|---|
| n ≤ 12 | O(n!) | Permutations, brute-force backtracking |
| n ≤ 20–24 | O(2n), O(2n·n) | Subset enumeration, bitmask DP |
| n ≤ 500 | O(n3) | Floyd–Warshall, interval DP |
| n ≤ 5,000 | O(n2) | Nested loop, most 2-D DP |
| n ≤ 1e5–1e6 | O(n log n), O(n) | Sort + sweep, sliding window, heap, hashing |
| n ≥ 1e7 | O(n), O(log n), O(1) | Single pass, binary search, math formula |
Step 6 in depth: the two heuristics that shortlist a structure
Heuristic A — the shape of the input
| The input is… | First things to try |
|---|---|
| a sorted array | Binary search; two pointers |
| an unsorted array, and order doesn't matter | Sort it first; or hashing for counts/dedupe |
| a contiguous range question (subarray / substring) | Sliding window; prefix sums |
| a string with a dictionary / prefixes | Trie; hashing |
| a grid | BFS / DFS treating cells as graph nodes; DP if counting paths |
| “things connected to things” | Graph — build adjacency, then BFS / DFS / union-find |
| a tree / hierarchy | Recursion: solve node from children's answers |
| a stream, or “top / kth” | Heap |
| intervals / ranges / a calendar | Sort by start, sweep line |
| n ≤ 20 and “subsets of items” | Bitmask |
Heuristic B — what am I optimising / producing?
| The ask | Usual tool |
|---|---|
| “Does X exist / have I seen X?” | Hash set |
| “How many / which is most frequent?” | Hash map of counts |
| “Best contiguous run” | Sliding window / Kadane |
| “Shortest / fewest steps” | BFS (unweighted), Dijkstra (weighted) |
| “Number of ways” / “min or max cost” | Dynamic programming |
| “All valid configurations” | Backtracking |
| “kth largest / smallest” | Heap, or quickselect |
| “Next greater / smaller” | Monotonic stack |
| “Minimum feasible value” | Binary search on the answer |
Brute force is not a waste of time — it's the map
Writing (or at least fully describing) the brute force does three things: it proves you understood the problem, it gives you a correctness oracle to test the fast version against, and its inefficiency points directly at the optimisation. “This inner loop recomputes a sum” → prefix sums. “This recursion recomputes fib(5) ten times” → memoisation. “This re-scans a sorted region” → two pointers or binary search.
1// Contract (triage step 2): 1 <= k <= len(nums). Pin it before coding;2// outside it, these two disagree (the first returns MinInt, the second panics).34// Brute force: for each right end, recompute the window sum from scratch.5func maxSum(nums []int, k int) int {6 best := math.MinInt7 for r := k - 1; r < len(nums); r++ {8 sum := 09 for i := r - k + 1; i <= r; i++ { // <-- repeated work10 sum += nums[i]11 }12 best = max(best, sum)13 }14 return best15}1617// The waste: nums[i] gets re-added k times.18// The fix: slide the window — add the entering element, drop the leaving one.19func maxSumFast(nums []int, k int) int {20 sum := 021 for i := 0; i < k; i++ {22 sum += nums[i]23 }24 best := sum25 for r := k; r < len(nums); r++ {26 sum += nums[r] - nums[r-k] // O(1) update27 best = max(best, sum)28 }29 return best30}
How to practise this
- For the next 20 problems you do, write the triage out in comments before coding. Steps 1–6 in words, then code.
- When you get one wrong, don't just read the solution — figure out which triage step would have caught it. Usually it's step 2 (missed an edge case) or step 5 (didn't spot the waste).
- Keep a personal table: problem → the one phrase that gave away the pattern. After ~30 entries you'll see the cues repeat. Log them in the Cue log; the Pattern Matcher is a starter version of the same table, built from the whole course.
- Run the 7-step triage every time; the steps you skip are the ones that bite.
- Constraints ⇒ target complexity. n ≤ 1e5 means no nested loop.
- Start from brute force, locate the repeated work, pick the structure that removes exactly that.
- Shortlist with two heuristics: the shape of the input, and what you're optimising.
- Train the translation skill deliberately — log the cue that revealed each pattern.
The part an AI chat can't give you
An LLM will happily explain a monotonic stack — and you should let it. What it won't do is decide what you learn next, remember that you got something wrong three weeks ago, or put it back in front of you today. That machinery is the course.
Think in half-open ranges [i,j); no …
Real cards from the two free modules, scheduled by the same SM-2 code the course runs. Every module's key points become cards.
Review 12 cards, then continue 14 Backtracking.
The dashboard picks the one next thing, so you never open the course and wonder what to do.
- “sorted” + “find a pair”→Two pointers
- “longest substring…”→Sliding window
- “next greater element”→Monotonic stack
- “top k” / “k closest”→Heap
- “number of ways”→DP over states
Two full indexes map the phrases you actually see in a problem to the structure or building block they imply. Browse the DSA one free →
That's 3 of 81.
The rest of Data Structures & Algorithms, all of Broader CS, and the full System Design track — including 19 case studies you run as mock interviews — plus every exercise and the spaced-repetition review, are one payment away.
Already bought it? Unlock