Stop grinding, start recognising: the 16-pattern model
Stop memorising 300 solutions and learn the sixteen shapes underneath them. A field guide to pattern recognition: the full inventory, telltale phrases, three dissections, and the practice habits that make it stick.
There is a moment every serious LeetCode grind hits around problem 150. You have seen sliding windows, two-sum farms, and enough rotated arrays to last a lifetime. And yet a brand-new hard still feels brand-new. The problem statement has different nouns, different constraints, and a subplot you have never seen. If you are memorising solutions, this is the moment the grind stops paying rent.
The fix is not more problems. The fix is a 16-pattern model: a small, fixed inventory of algorithmic shapes that sit underneath the vast majority of interview questions. Once you can name the shape in the first ninety seconds, the interview stops being a recall test and becomes the recognition test it was always supposed to be.
A pattern is not a trick. A pattern is the shape beneath the problem statement — and shapes generalise where raw details do not.
Why grinding stops working
Human memory stores gist better than surface detail. If you learn "longest substring without repeating characters" as a story about characters and indices, you can only re-solve variations about characters and indices. But if you learn the shape behind it — a contiguous segment that must keep a window-invariant satisfied — you instantly own "longest subarray with at most two distinct values", "minimum window substring", and a dozen unrelated-looking problems.
The numbers back this up. Companies rotate a finite canon of question families, and most middle-of-the-road interview problems are one of the sixteen shapes below with different clothing. That is why pattern-first study beats volume-first study: the same idea appears again and again, and recognition gets cheaper every single time you meet it.
The sixteen, mapped
Here is the full inventory, grouped by the kind of thinking each one demands.
- Pointer & window patterns: 1. Sliding Window, 2. Two Pointers, 3. Fast & Slow Pointers.
- Array-structure patterns: 4. Merge Intervals, 5. Cyclic Sort, 6. In-place Reversal of a Linked List.
- Tree patterns: 7. Tree BFS, 8. Tree DFS.
- Ordering and search patterns: 9. Modified Binary Search, 10. Two Heaps, 11. Top K Elements, 12. K-way Merge.
- Combinatorial patterns: 13. Subsets, 14. Bitwise XOR, 15. 0/1 Knapsack.
- Dependency patterns: 16. Topological Sort.
You will not need all sixteen on a given morning. But each one maps to a family of problems, and the map is the deliverable. Keep this inventory next to your practice session until the names are boring.
How recognition actually works
Recognition is not a vibe. It is three questions you run in the first ninety seconds of reading a problem:
- What is the input shape, and is it sorted, ordered, or bounded? Sorted data with a target instantly points at Two Pointers or Modified Binary Search.
- Is there a contiguous segment or a fixed-size sub-structure? Contiguous plus "best, longest, shortest window" is Sliding Window. Non-contiguous pairs are usually Two Pointers.
- What does brute force cost, and which pattern cancels which term? An O(n2) pair scan usually collapses to O(n) with two pointers; an O(n2) subarray scan usually collapses to O(n) with a window; an O(k·n) top-k scan collapses to O(n log k) with a heap.
Each pattern has telltale phrases. Sliding Window: "contiguous", "subarray", "at most k", "smallest window". Two Pointers: "sorted", "pair", "three numbers sum to zero". Fast & Slow: "does it have a cycle", finding the middle of a list. Top K: "k largest", "k most frequent", "k closest". Topological Sort: "prerequisites", "depends on", "valid order of tasks". Learn the telltale list like you would learn a foreign language's grammar tables — because that is exactly what it is.
Three patterns, dissected
Sliding Window: keep a window-invariant
Take "longest substring without repeating characters". A brute force checks every start and end pair in O(n2). The window version keeps both ends moving right and stores the last index of each character. The invariant: the window never contains a duplicate, because when you meet a repeat, you jump the left edge past the previous occurrence. Sliding windows only ever move forward, never backwards.
int left = 0, best = 0;
Map<Character, Integer> last = new HashMap<>();
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
left = Math.max(left, last.getOrDefault(c, -1) + 1);
best = Math.max(best, right - left + 1);
last.put(c, right);
}
return best;
The invariant is the whole insight. Once left and right only ever advance, total work is two passes of the string, and every substring variant — fruits into baskets, longest nice subarray, minimum window — is the same skeleton with a different invariant.
Two Pointers: exploit the order
Given a sorted array and a target sum, find two numbers that add to it. Brute force is a nested loop. Two pointers start at both ends and shrink from whichever side misses the target, using the order as the source of correctness. Because the array is sorted, moving the left pointer up increases the sum and moving the right pointer down decreases it, so no candidate is skipped.
int lo = 0, hi = nums.length - 1;
while (lo < hi) {
int sum = nums[lo] + nums[hi];
if (sum == target) return new int[]{lo, hi};
if (sum < target) lo++; else hi--;
}
return null;
When you hear "sorted" and "pair", stop trying to be clever and watch the pointers. The pattern kills the inner loop, and problems like "the container that holds most water" or "three-sum closest" are the same idea wearing different hats.
Modified Binary Search: find the half that is ordered
"Search in a rotated sorted array" scares people because the classic binary search precondition is violated. The fix is to check, at every midpoint, which half is properly ordered and then decide whether the target lives inside it. One ordered half always exists in a rotation, and it is always enough to make a decision.
int lo = 0, hi = n - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] == target) return mid;
if (nums[lo] <= nums[mid]) {
if (nums[lo] <= target && target < nums[mid]) hi = mid - 1;
else lo = mid + 1;
} else {
if (nums[mid] < target && target <= nums[hi]) lo = mid + 1;
else hi = mid - 1;
}
}
return -1;
The classic O(log n) budget survives. The pattern's superpower is that it applies to any problem where the answer is the first index where some predicate flips — a peak element, the first bad version, the floor of a square root — and to the whole family of binary-search-on-the-answer problems.
The 80/20 of the sixteen
In real interview cycles, six patterns do most of the work: Sliding Window, Two Pointers, Tree DFS, Modified Binary Search, Top K Elements, and Merge Intervals. They appear in the widest variety of mid-level problems, so they deserve the most repetitions. The remaining ten are recognition insurance: you do not need to be fluent, but you need to recognise them fast enough to avoid staring at a wall. One solid session per pattern turns an unknown into a remembered shape.
Practice so the pattern sticks
How you practise matters more than how much. Three habits make recognition stick:
- Cluster first, then scramble. Learn a pattern with five same-pattern problems, then switch to scrambled mixed sets so your brain has to identify rather than assume.
- Name it out loud. Before writing any code, say one sentence: "This is Sliding Window with a distinct-count invariant." If you cannot name it, you are not ready to code it.
- Track the miss. When you identify the wrong pattern, that is your highest-value data point. Review your pattern map when it happens — the pile of those misses is your personal weaknesses list.
Our pattern catalogue describes every pattern with its telltale phrases and skeleton code, and the Two Pointers practice set shows what a same-pattern drill block looks like. For a fixed arc through the full inventory, the study tracks sequence the patterns so that recognition arrives before the interview, not during it.
The interview is an identification test
Interviewers are not scoring your ability to solve problem number 31. They are scoring your ability to take an unfamiliar statement, find the shape, and execute the shape competently. That is a different skill, and it is the skill the 16-pattern model trains. When you start a problem by saying "this looks like Sliding Window because the substring is contiguous and we need a bounded distinct set", you are showing the interviewer the recognition engine itself. They will happily follow a confident identification to a correct solution. They will grudgingly watch a hundred lines of brute force. Recognise first, code second, and the ceiling on your performance stops being your memory and becomes your judgement.