Recognise the shape, not the problem
Interview problems reuse a small catalogue of shapes. The candidate who memorises two hundred problems is running a losing race against the candidate who can classify a new problem in twenty seconds. The difference between them is pattern recognition, a skill that turns out to be learnable.
A software engineer I mentored kept failing interviews. Not because she couldn't code (her coding was clean) but because she spent the first fifteen minutes of every problem trying to recall whether she'd seen it before. When she had, she sped through. When she hadn't, she froze.
The cure was straightforward to state and surprisingly hard to internalise: she was studying the wrong unit. Interview problems are not the unit to study. Shapes are. A "shape" is a diagnostic fingerprint, a combination of input type, question form, and constraints that maps to a small family of algorithms. Once you see the shape, the algorithm is usually one of two or three options. Then coding is just writing down the answer.
The catalogue is smaller than you think
Here is the full catalogue of shapes that covers something like ninety percent of the technical-screen problems posted on Leetcode's medium tier:
- Sorted array + pair/triplet question → two pointers converging. O(n) or O(n²).
- Unsorted array + "is there a pair summing to X" → hash map, seen-so-far. O(n).
- Contiguous subarray + monotone property → sliding window. O(n).
- "Does X appear in sorted input" → binary search. O(log n).
- "Smallest X such that predicate holds" (monotone) → binary search on the answer. O(log range · check).
- Linked list + meeting/mid/cycle → fast and slow pointers. O(n), O(1).
- Tree + "property of each node in terms of subtree" → post-order recursion. O(n).
- Tree + "shortest path in node count" → BFS.
- Graph + "reachable from X" → DFS or BFS, O(V+E).
- Weighted graph + shortest path → Dijkstra (non-negative weights) or Bellman-Ford (general).
- Directed graph + ordering of nodes → topological sort.
- "Optimal substructure + overlapping subproblems" → DP. Name the state.
- Top-K of a stream → heap of size K. O(n log k).
- Sorted output from multiple sorted inputs → merge with heap.
- Count distinct elements with high memory → hash set. Without high memory → HyperLogLog, but this is rarely asked.
That's fifteen shapes. You will encounter them again and again in different disguises. The candidates who struggle are the ones trying to recognise the disguise. The candidates who fly through are the ones who see the shape underneath.
The diagnostic questions
When you read a new problem, run through a diagnostic in your head (twenty seconds, no pen down, no code) answering five questions:
- What's the input shape? Array, sorted array, linked list, tree, graph, string, number?
- What's the output shape? Yes/no, count, index, value, sequence, optimum?
- What are the constraints? n ≤ 10? 10⁵? 10⁹? Input size often reveals the expected complexity, n ≤ 20 suggests bitmask, n ≤ 10⁴ suggests O(n²), n ≤ 10⁵ suggests O(n log n), n ≤ 10⁹ suggests O(log n) or O(1).
- Is anything monotone? A monotone structure often implies a two-pointer or binary-search shape.
- Is there a natural decomposition into subproblems? If yes, DP is on the table.
A worked diagnosis, start to finish
Take a problem none of us have seen stated this way: "Given an array of 200,000 positive integers and a target T, return the length of the shortest contiguous run whose sum is at least T, or 0 if none exists." Run the five questions and watch the search space collapse.
Input shape: an unsorted array, but with a promise that every element is positive. Output shape: a minimum length, so an optimum rather than a yes or no. Constraints: n is 2 x 10^5, which rules out anything quadratic, since 4 x 10^10 operations will not finish, and points at O(n) or O(n log n). Monotonicity: this is the question that pays. Because every element is positive, extending a run to the right strictly increases its sum, and shrinking from the left strictly decreases it. The sum is monotone in both directions. Decomposition: there is no obvious subproblem structure, so dynamic programming is not indicated.
A contiguous run, a monotone property, and a minimisation target is the sliding-window fingerprint exactly. Expand right until the sum reaches T, then shrink left while it still does, recording the length at each valid moment. Each pointer crosses the array once, so the cost is O(n), about 4 x 10^5 pointer moves against a budget that comfortably allows 10^8. Total diagnosis time: under twenty seconds, and not one of those seconds was spent trying to remember a problem.
Now change one word. Drop "positive" and allow negative numbers. Monotonicity dies instantly, because extending a run can now lower its sum, and the sliding window's invariant goes with it. The shape is no longer a window; it is a prefix-sum problem with a monotonic deque or a hash map, depending on whether the target is a lower bound or an exact match. One word in the constraints moved the problem to a different family. That is why the constraints are a diagnostic input and not decoration.
The cue-to-shape table
Most of the diagnostic compresses into a lookup. The left column is what you read in the prompt; the right column is where to look first.
| Cue in the prompt | Likely shape | Typical cost | What kills it |
|---|---|---|---|
| "sorted array" plus a pair or triplet | Converging pointers | O(n) to O(n^2) | Input is not actually sorted |
| "contiguous" plus a monotone measure | Sliding window | O(n) | Negative values break monotonicity |
| "subarray sums to exactly k" | Prefix sums plus hash map | O(n) | Asking for a maximum instead of a count |
| "smallest x such that P(x)" with P monotone | Binary search on the answer | O(log range * check) | P is not actually monotone |
| n <= 20, "all subsets" or "assignments" | Bitmask enumeration or bitmask DP | O(2^n) or O(2^n * n) | n creeps above about 25 |
| n up to 10^9, answer is a count | Closed form, digit DP, or O(log n) | O(log n) | Reaching for iteration at all |
| "k-th largest" or "top k of a stream" | Heap of size k, or quickselect | O(n log k), O(n) average | Needing the full order as well |
| "must come before" or "dependencies" | Topological sort | O(V + E) | Edge direction written backwards |
| "shortest path", unweighted | BFS | O(V + E) | Weights appear later in the prompt |
| "property of a node in terms of its subtree" | Post-order recursion | O(n) | Needing to return two different values |
Notice that the fourth column matters as much as the second. Knowing a shape's failure mode is what lets you abandon a wrong diagnosis in ten seconds instead of twenty minutes, and it is the difference between a candidate who recovers and one who does not.
That's it. Those five questions will usually narrow the shape to one or two candidates. You then state your plan aloud, "I think this is a sliding window; the right pointer expands, the left contracts when the window has more than k distinct characters", and start coding. The interviewer sees reasoning, not recall. That's what they're evaluating.
How to train the eye
Pattern recognition is a trained skill, not a talent. The training is unglamorous: do problems, then immediately classify them by shape before reading the solution. If your shape is wrong, the solution will tell you, and the wrongness is where you learn.
A useful drill: after each problem, write one sentence of the form "This was a [shape] problem, diagnosed by [constraint/cue], solved with [algorithm], in O([complexity])." After twenty such sentences, the shapes start to stabilise. After a hundred, the recognition is automatic.
Another drill: read only the first paragraph of a problem, then write the shape you expect before reading further. If you guess right consistently, you're done practising. If you guess wrong more than a third of the time, keep going.
Where pattern recognition fails
Three failure modes are worth naming. First, forcing a shape that doesn't fit. If a problem looks like a sliding window but doesn't have a monotone invariant, sliding window will produce wrong answers. When the diagnostic says "this is shape X" but the implementation resists, stop and re-diagnose. Don't push a fit through.
Second, ignoring the disguise entirely. Pattern recognition is the starting point, not the solution. Once you identify the shape, you still have to handle the specific wrinkles, the edge cases, the constant factors, the language-specific gotchas. A shape tells you where to look; the problem tells you what to find.
Third, skipping the reasoning. Interviewers evaluate your thought process, not just your output. A candidate who blurts "this is DP, so here's the code" without explaining why misses most of the signal. State the diagnosis. Show the work.
Why this works
Chess masters don't compute every move; they see known positions. Doctors don't work through every differential; they see recognisable presentations. Senior engineers don't think about every problem from scratch; they see familiar shapes and jump to the known solution space. Pattern recognition is expertise. The trick is that, for algorithm problems, the number of patterns is genuinely small (fifteen shapes cover most of the surface) so expert-level recognition is achievable within a reasonable training budget. A few hundred problems with intentional classification practice is enough.
If you have been grinding problems without classifying them, you have been taking the expensive route. Switch. The same hours, spent on recognition instead of memorisation, produce a much better interview performer.
Frequently asked questions
How many problems do I need before the shapes become automatic?
In my experience it is closer to a hundred with deliberate classification than to five hundred without it. The variable that matters is not the count but whether you name the shape before reading the solution and check yourself afterwards. Fifty problems classified out loud beat three hundred skimmed.
What if a problem genuinely does not match any shape?
It happens, and it is rarer than it feels. Most often the problem is a composite: a graph shape wrapped around a DP shape, or a binary search whose predicate is itself a greedy check. Try to name the outer shape first and treat the inner question as a subroutine. If it truly matches nothing, fall back on brute force, state its complexity, and optimise from there, which is a perfectly respectable interview trajectory.
Does this work for system design interviews too?
The mechanism transfers, the catalogue does not. System design has its own set of recurring shapes, such as read-heavy with a cache, write-heavy with a queue, and fan-out on read against fan-out on write. The habit of diagnosing before designing is the transferable part; you have to build the second catalogue separately.
Further reading
Each of the fifteen shapes above has a module on this site that explains its mechanics in depth. If you want a single starting point, read Arrays and then Two Pointers & Sliding Window back-to-back, those two modules cover five of the fifteen shapes. Hash Maps covers three more. A focused week on these three modules will change how you read problems.