
How to actually get good at LeetCode (a coach's method, not a grind list)
Article Summary
Stop grinding 500 problems. A pattern-recognition method built around ~15 core patterns, the 25-minute rule, and what interviewers actually grade.
A student messaged me last winter, equal parts proud and miserable: he'd solved 380 LeetCode problems and just bombed a phone screen on a problem he was sure he'd done before. He had — twice. But he'd solved it by recognising the exact problem, not the underlying idea, so when the interviewer changed the wording and the constraints, the memory gave him nothing. He'd spent four months building a library of answers to specific questions and almost none building the skill of deriving an answer from scratch.
I've coached a lot of people through interview prep, and this is the single most common failure mode I see: treating LeetCode as a reading list to finish rather than a skill to train. Nobody asks "how many novels do I need to read before I can write one?" — but people genuinely ask "how many problems before I'm ready?" Wrong unit. The question isn't how many. It's can you recognise the shape of a problem and reconstruct the solution under pressure while talking. This post is the method I actually teach.
The grind list is a trap
The "just do 500 problems" advice isn't malicious — it's just lazy, and it confuses correlation with cause. Yes, people who've solved a lot of problems tend to do well. But it's not the count that made them good; it's that somewhere in those problems they internalised a small set of reusable patterns. You can get the same result with a fraction of the volume if you train deliberately instead of grinding for a number.
Here's the uncomfortable math. There are well over three thousand problems on LeetCode. You will never do them all, and you don't need to, because the vast majority are variations on a small number of underlying patterns. Learn the patterns and a brand-new problem stops being "a problem I haven't seen" and becomes "oh, that's a sliding-window problem wearing a costume." Memorise individual solutions and every reworded problem is a fresh cliff.
Takeaway: your goal isn't a solved-problem count. It's pattern fluency — the speed at which you map an unseen problem to a technique you know.
The ~15 patterns that cover most of it
When people talk about "LeetCode patterns," they mean recurring solution structures that show up across hundreds of problems. The commonly taught core set — and I'm naming them honestly, not padding the list to hit a round number — looks like this:
- Two pointers — pairs in a sorted array, removing duplicates, partitioning.
- Sliding window — longest/shortest contiguous subarray or substring meeting a condition.
- Fast and slow pointers — cycle detection in linked lists, finding a midpoint.
- Hash-map counting / frequency — anagrams, "have I seen this before," counting occurrences.
- Binary search — sorted arrays, and "search on the answer" problems that aren't obviously sorted.
- Tree DFS (depth-first) — path sums, tree validation, recursion over structure.
- Tree / graph BFS (breadth-first) — shortest path on unweighted graphs, level-by-level traversal.
- Backtracking — permutations, combinations, subsets, anything generating all candidates.
- Dynamic programming — overlapping subproblems and optimal substructure (the big, scary family).
- Heap / top-K — "k largest/smallest/most frequent," merging sorted streams.
- Intervals — merging, inserting, and overlap problems on ranges.
- Stack / monotonic stack — matching brackets, "next greater element," parsing.
- Prefix sums — range-sum queries, subarray-sum-equals-k.
- Greedy — locally optimal choices that provably reach a global optimum.
- Linked-list manipulation — reversal, merging, the pointer-surgery family.
That's fifteen. It's not exhaustive, and the boundaries blur — DP and backtracking overlap, BFS and DFS are cousins — but if you can genuinely recognise and execute those, you've covered most of what a standard coding interview throws at you. Start with the first half-dozen (two pointers, sliding window, hash-map counting, binary search, DFS, BFS). They're the highest-return and they show up everywhere. The pattern-by-pattern path is exactly how I structure one-on-one DSA coaching — we go deep on one pattern at a time rather than scattering across random problems.
The 25-minute rule (where the learning actually happens)
This is the heart of the method, and it's where most people leave all their gains on the table. The rule:
- Attempt the problem cold for 25 minutes. Real effort. Whiteboard or comments, sketch the idea, try to code it. The struggle is the point — it's what builds the retrieval pathways.
- If you're stuck after 25 minutes, read the solution. Not the code first — read enough to grasp the idea, then try to finish it yourself. Understand why it works, not just that it does.
- The next day, re-derive it from scratch. Blank editor, no notes. Can you rebuild the solution from the idea alone?
That third step is the one everybody skips, and it's the only one that proves anything. Reading a solution and nodding gives you the warm feeling of understanding without the substance — it's recognition, not recall, and interviews demand recall. If you can't reproduce it the next day, you didn't learn it; you watched it. Re-deriving from scratch is the difference between "I've seen this" and "I can do this."
A practical consequence: it's far better to deeply learn 80 problems via this loop than to skim 400. The student from the opening had it backwards — volume up, depth down. We flipped it, and his second-round interview two months later went fine.
Explaining out loud is half the interview
Here's something candidates consistently underweight: in a real interview, roughly half of what's being assessed is how you communicate, not whether you reach the optimal solution. The interviewer is imagining working with you. A correct answer delivered in total silence, then dumped on screen, reads worse than a slightly-less-optimal answer where you narrated your thinking, named your assumptions, and discussed trade-offs.
So you have to practise the talking, and you can practise it alone:
- Narrate every problem out loud, to an empty room. State the brute force first. Say what's slow about it. Say what data structure might fix it and why. It feels ridiculous. Do it anyway — the awkwardness is exactly the skill you're building.
- Rubber-duck it. Explain your approach to an inanimate object as if it's a junior engineer. If you can't explain it simply, you don't understand it well enough yet, and you'll find that out at your desk instead of in the interview.
- Record yourself occasionally. Painful, effective. You'll hear the long silences and the hand-waving you don't notice in the moment.
The signal interviewers are listening for: do you ask clarifying questions, do you state your plan before coding, do you talk through trade-offs (time vs space, readability vs cleverness), do you test your own code? Those are learnable, and they're worth as much as the algorithm.
A worked example: brute force, then pattern-upgraded
Let's make this concrete with an easy classic — Two Sum: given an array of integers and a target, return the indices of the two numbers that add up to the target.
The instinct is to check every pair. That's the brute force, and you should always state it first in an interview — it shows you can solve the problem at all before you optimise:
def two_sum_brute(nums, target):
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
if nums[i] + nums[j] == target:
return [i, j]
return []This works. It's O(n²) time — two nested loops over the array. In an interview you'd say exactly that: "This is correct but quadratic; for each element I'm scanning the rest of the array. Can I avoid the inner loop?"
Now the pattern upgrade. The key realisation: for each number x, I'm really asking "have I already seen target - x?" — and "have I seen this before" is the signature of the hash-map pattern. A hash map answers that in O(1), so I trade a little memory for a lot of speed:
def two_sum(nums, target):
seen = {} # value -> index of values we've passed
for i, x in enumerate(nums):
need = target - x
if need in seen: # have we already seen the complement?
return [seen[need], i]
seen[x] = i # remember this value and where it was
return []One pass, O(n) time, O(n) space. Same problem, but recognising "have I seen the complement?" as a hash-map question collapsed a quadratic solution into a linear one. That recognition step — not the typing — is the whole skill. Get fluent at it across fifteen patterns and most interview problems start to feel familiar even when you've never seen the exact wording.
| Brute force | Pattern-upgraded | |
|---|---|---|
| Approach | Check every pair | Hash map of complements |
| Time | O(n²) | O(n) |
| Space | O(1) | O(n) |
| The insight | — | "Have I seen target - x?" → hash map |
Spaced repetition for problems
Patterns fade if you don't revisit them, the same way vocabulary in a foreign language does. So treat problems like flashcards. Keep a simple log — problem, pattern, date, and how it went (got it cold / needed a hint / had to read the solution). Then revisit on a spreading schedule: a problem you struggled with comes back in a few days, then a couple of weeks, then a month. The ones you nail, you push further out. The ones that keep biting, you keep close.
The point isn't a fancy system; a plain spreadsheet works. The point is that you re-derive the troublesome ones on a schedule instead of solving each problem once and trusting it'll stick. It won't. A pattern you understood in March will be hazy by June if you never touch it again — and interviews have a way of landing in June.
What interviewers actually grade (and a realistic timeline)
Let me say the quiet part plainly, because it reframes everything above. Interviewers are not grading whether you produced the textbook-optimal solution from memory. They're reading for signal: Can you understand a problem? Do you communicate your thinking? Can you reason about trade-offs? Do you write code that runs and test it yourself? Can you take a hint gracefully and adjust? A candidate who reasons aloud to a clean, well-explained O(n log n) solution very often clears the bar over one who silently regurgitates a memorised O(n) and can't explain it.
Which is why the pattern method beats the grind: it builds the actual graded skills — recognition, derivation, communication — instead of a brittle memory of specific answers.
And the timeline, honestly: this takes months, not weeks. If you're starting from rough, plan on a few months of consistent, deliberate work — patterns, the 25-minute loop, talking out loud, spaced review. Anyone promising interview-ready in two weeks is selling something. The good news is that consistent and deliberate beats frantic and high-volume every time, and the skills you build this way don't evaporate the week after the interview — they make you a better engineer.
The recap: learn ~15 patterns, start with the core six. Use the 25-minute rule and re-derive the next day. Practise explaining out loud, alone, until it's natural. Space your repetition. And remember the interview grades communication and trade-offs as much as correctness. Depth over count, every time.
If you'd rather not figure out which pattern a problem belongs to alone — that recognition step is genuinely faster to learn with someone pointing it out in real time — that's exactly what I do in one-on-one DSA sessions. The first session is free, and we can start from a mock interview to see where your real gaps are rather than guessing.
Enjoyed this post? Get the next one in your inbox.
A short, useful email when there's a new tutorial, study guide, or career-prep post on the blog. No spam, unsubscribe anytime.
Written by Ali Jabbary
M.Sc., P.Eng. • Expert Data Scientist & ML Engineer with 10+ years of experience. 500+ students helped worldwide. Specializing in Python, AI/ML, and turning complex problems into simple solutions.


