Most coding problems are not new. They wear different costumes, but underneath they reuse the same handful of moves. Once you can name those moves, a blank problem stops feeling like a blank page and starts feeling like "which of these do I already know?"
I'm not going to promise you a magic list that solves everything. But there's a small set of patterns that shows up again and again, in interviews and in real work. Learn these well and you'll recognize the shape of most problems fast.
Here they are, with the tell that should make you reach for each one.
Two pointers
You have a sorted array or a string, and you're comparing or moving toward something from both ends or at two speeds.
The tell: "pair that sums to X," "remove duplicates in place," "is this a palindrome," "merge two sorted things." If brute force is a nested loop over the same array, two pointers often collapses it to one pass.
Start with one pointer at each end, or one slow and one fast. Move them based on a condition. That's it.
Sliding window
This is two pointers with a job: track a contiguous chunk and expand or shrink it.
The tell: "longest substring without repeats," "smallest subarray that sums to at least K," anything about a window over a sequence. You grow the window to satisfy a condition, then shrink it to stay valid, and you keep the best answer you've seen.
If you find yourself recomputing a sum or a count over a range you already looked at, that's the signal to slide instead.
Hash map for lookups and counting
The most boring pattern and the one I use most. A hash map turns "did I see this before?" and "how many of these are there?" into constant-time questions.
The tell: "find the pair," "first non-repeating character," "group these by something," "have we visited this." Two Sum is the classic. So is almost every counting problem.
When a solution feels like it needs a second loop just to check what you already passed, store it in a map on the first pass instead.
Fast and slow pointers
Two pointers, but one moves twice as fast. Mostly for linked lists and cycle detection.
The tell: "does this linked list have a cycle," "find the middle node," "find where the cycle starts." The fast pointer either falls off the end or laps the slow one.
It's a narrow pattern, but when it fits, nothing else is as clean.
Binary search
Not just for finding a value in a sorted array. The real idea is: you can throw away half the search space based on one check.
The tell: anything sorted, "find the smallest X that works," "minimize the maximum." If you can ask a yes/no question about a candidate answer and the answers go no-no-no-yes-yes-yes, you can binary search the boundary.
This one trips people up because the hardest part is the off-by-one edges. Practice the template until the boundaries feel automatic.
BFS and DFS on graphs and trees
A huge share of problems are graphs in disguise. Grids, mazes, dependencies, social connections, file systems.
The tell: "shortest path in an unweighted grid" is BFS. "Can I reach," "all paths," "connected components" lean DFS. Trees are just graphs without cycles, so the same traversals apply.
Learn one clean BFS with a queue and one clean DFS with recursion or a stack. Most graph problems are a variation on those two skeletons.
Dynamic programming
The scary one. But the core question is simple: can I build the answer from answers to smaller versions of the same problem?
The tell: "how many ways," "minimum or maximum cost to reach," "can I make this total," and overlapping subproblems where plain recursion recomputes the same thing.
Start by writing the slow recursive solution. Then cache the repeated work. That memoized version is already DP, and you can convert it to a table later if you want.
Why this works
These patterns cover a lot because most problems are built from the same primitives: scan a sequence, remember what you saw, search a space, walk a structure, or build up from smaller results.
When you sit down with a new problem, run through the tells. Is it sorted? Binary search or two pointers. Counting or pairing? Hash map. A window over a sequence? Slide it. Reachability or paths? BFS or DFS. Smaller-version overlap? DP.
You won't always be right on the first guess, and some problems mix two patterns. That's fine. The goal isn't to memorize solutions. It's to shrink the unknown so you're choosing between tools you know instead of inventing from scratch.
The way you build this instinct is reps. Solve a few problems per pattern, then come back a week later and solve a few more without looking. After enough mock interviews and timed practice, you stop reading a problem and asking "what is this?" and start asking "which pattern is this?" That shift is most of what separates someone who freezes from someone who starts typing.
Pick one pattern this week. Do five problems on it. Then move to the next.