Skip to content

PatternDojo#

You can write code — but hand you an unfamiliar problem and you freeze. Or you used to solve these easily, and after leaning on AI, you can't anymore. This is the path back.

Every problem here is grouped by the problem-solving pattern it teaches, and the patterns are sequenced so each one builds on the last. You don't just get a list of links — you get the triggers for recognising each pattern, the anti-triggers for when not to reach for it, and a clear benchmark for when you've truly learned it.

Not sure where to start? If you're new to structured practice, begin at the warm-up below — it's a handshake, not a curriculum. If you're an experienced developer returning after a gap, each pattern's challenge problem doubles as a test-out: solve it cleanly and move on. Read the How to Practice guide first — it makes everything else work better.

Stage 0 — Warm-Up: Shake the Rust Off#

Not patterns — just easy wins. Prove to yourself you can take a problem from description to a working, accepted solution. Seniors: do one or two and move on.

  • Warm-Up — This isn't a pattern — it's a handshake. If you haven't solved a problem on a coding judge in a while (or ever), start here. No new concepts, no techniques to learn. Just prove to yourself that the machinery works: you can read a problem, write code, and hit Submit.

Stage 1 — Foundations: Linear Patterns#

The highest-leverage patterns, and the ones hiding inside almost everything later.

  • Frequency Counter — The moment you catch yourself about to write a loop inside a loop — comparing every item against every other item — stop. A frequency counter does the same job in a single pass by remembering what you've already seen. You spend a little memory to buy a lot of speed.
  • Two Pointers — Two indices walk the array — usually from both ends toward each other, or one behind the other. Because each pointer only ever moves in one direction, the whole array is covered in a single pass with no extra memory. On sorted data, comparing the two ends tells you which pointer to move, so you discard half the useless comparisons for free.
  • Sliding Window — A window (a contiguous stretch) slides along the data. You extend the right edge to grow it and pull the left edge in to shrink it, keeping some running summary — a sum, a count, a character tally — updated as you go. Because each element enters once and leaves at most once, the whole thing runs in linear time even though it feels like nested loops.
  • Prefix Sum — Precompute a running total so that the sum of any range becomes one subtraction. You pay O(n) once and every later range-sum query is free. Combined with a hash map, it solves a whole family of "count the subarrays that sum to K" problems that look impossible at first glance.

Stage 2 — Sorting & Searching#

  • Binary Search — Halve the search space every step by asking one yes/no question. The array doesn't strictly need to be sorted — what it needs is a monotonic predicate: some property that's false, false, false, then true, true, true. Once you see that shape, you can binary search on it, even when the "array" is a range of possible answers rather than real data.
  • Merge Intervals — Sort the intervals, then walk them once, keeping a "current" interval open and either extending it (if the next one overlaps) or closing it and starting a new one. Almost every interval problem is this same loop with a different closing condition.

Stage 3 — Linked Lists#

  • Fast & Slow Pointers — Two pointers move through the structure at different speeds. If there's a loop, the fast one eventually laps the slow one and they collide. If there isn't, the fast one falls off the end. The same trick, stopped halfway, finds the middle of a list in one pass.
  • In-Place Reversal — Walk the list holding three references — previous, current, and next — and flip each node's pointer backwards as you pass. The entire pattern is "save the next node before you overwrite the link, or you lose the rest of the list."

Stage 4 — Stacks & Queues#

  • Stack Matching — Push things that are waiting to be resolved; pop when the thing that resolves them arrives. The stack is a memory of "what's still open," and the last thing opened is always the first thing that must close.
  • Monotonic Stack — Keep a stack whose values only ever increase (or only decrease). When a new element violates that order, pop everything it beats — and that pop is the answer for each popped element. Every item is pushed once and popped once, so despite the inner loop it's linear.

Stage 5 — Recursion & Trees#

  • Recursion Fundamentals — Solve a problem by assuming you can already solve a smaller version of it, then defining how to combine that smaller answer into the full one. The whole skill is trusting the recursive call instead of trying to trace every level in your head.
  • Tree DFS — Go as deep as you can down one branch, then come back up and take the next. The recursion handles the bookkeeping. The only real decision is when you do the work: before the children (preorder), between them (inorder), or after both have reported back (postorder) — and that choice is what makes a problem easy or impossible.
  • Tree BFS — Visit the tree in rings — everything at depth 0, then depth 1, and so on — using a queue. The one idea worth internalising: record the queue's size at the top of each round, and that count is the current level, which is how you get level-by-level output from a flat queue.

Stage 6 — Heaps & Top-K#

  • Top K Elements — Keep a heap of exactly K items as you stream through the data, evicting the worst each time it overflows. You never sort the whole input — you only ever maintain the K that matter.
  • Two Heaps — Split the data into a lower half (max-heap) and an upper half (min-heap), kept balanced in size. The two heap tops sit exactly at the middle of the data, so the median is always one glance away, no matter how much data streams in.

Stage 7 — Backtracking#

  • Subsets — For each element, you make one decision — take it or leave it — and explore both branches. The recursion tree is the answer set. Backtracking simply means undoing your choice on the way back up, so the next branch starts clean.
  • Permutations — Same machinery as subsets, but now order matters, so at each step you pick any unused element rather than just deciding yes or no on the current one. The "used" bookkeeping is the whole difference.

Stage 8 — Dynamic Programming#

The most-atrophied skill for returning devs — so it gets real depth, and it's built last.

  • 1-D DP — The answer at position i depends only on a few earlier answers. Store those, and the exponential recursion collapses into a single left-to-right pass over an array. That's the entire idea; everything else in DP is a variation on what you store.
  • 2-D DP — The state now needs two coordinates, so the table becomes a grid: each cell's answer is built from its neighbours above and to the left. Filling it in the right order is the whole job.
  • Knapsack DP — You're choosing items against a budget. For each item and each possible remaining budget, the answer is the better of "take it" and "skip it." Whether you may reuse an item — and therefore which direction you iterate the budget — is the only thing that separates the two famous variants.
  • Sequence DP — Compare two sequences (or a sequence against itself) position by position, where each cell answers "the best I can do using the first i of one and the first j of the other." Match, and you extend a previous answer; mismatch, and you take the best of skipping one side or the other.
  • Palindrome DP — A string is a palindrome if its ends match and the string inside them is a palindrome — which is a recursive definition begging for a table. But there's a rival approach worth knowing: stand at each character (and each gap) and expand outward while the ends match. Same O(n²) time, but O(1) space and far less code.

Stage 9 — Graphs#

  • Graph Traversal — A grid is a graph in disguise — every cell is a node and its neighbours are its edges. Once you see that, "count the islands" and "find the shortest path" become the same two algorithms you already met on trees, plus one new obligation: mark what you've visited, because unlike a tree, a graph can walk you in circles.
  • Topological Sort — Repeatedly take any node with nothing left blocking it, remove it, and see what that unblocks. The order things come out is a valid order to do them in. If you get stuck with nodes remaining, they're waiting on each other — you've found a cycle.

Stage 10 — Optional Extensions#

Add these once the core is stable; each appeared in only one or two of the research passes.

  • Greedy — Take the best-looking option right now and never reconsider. It's the simplest strategy imaginable, and it's usually wrong — the entire skill is recognising the rare problems where it's provably right.
  • Bit Manipulation — Work on the binary representation directly. The single idea worth its weight: XOR-ing a number with itself gives zero, so XOR-ing an entire array where everything appears twice except one thing leaves exactly that thing behind.
  • Union-Find — Every element points to a "leader." To merge two groups, point one leader at the other. To ask "are these two connected?", follow both to their leaders and compare. Path compression flattens the chains as you go, so the structure gets faster the more you use it.
  • Dijkstra — BFS explores in rings because every step costs the same. When steps cost different amounts, replace the queue with a priority queue so you always expand the cheapest-known node next. That one substitution is the whole algorithm.
  • Tries — A tree where each edge is a character, so every path from the root spells a prefix. Looking up a word costs only its own length — completely independent of how many words you've stored.
  • Cyclic Sort — When an array holds the numbers 1 to n in some scrambled order, every value has a natural home: value v belongs at index v-1. Walk the array putting each number where it belongs, and whatever's left out of place is the answer — the missing one, the duplicate, the mismatch.

Why Focus on Coding Patterns?#

Learning to code is only the first step. The real challenge in software engineering, especially during technical interviews, is knowing how to approach an unfamiliar problem. That's where coding patterns come in.

Instead of memorizing hundreds of individual solutions or endlessly grinding problems, mastering coding patterns allows you to recognize the underlying structure of a problem. Whether you're dealing with arrays, strings, linked lists, or trees, a pattern like Two Pointers, Sliding Window, or Fast & Slow Pointers often reveals the optimal solution. Because these concepts are conceptual, they apply universally across all coding languages.

What You Will Learn at PatternDojo#

PatternDojo is not just another list of LeetCode problems or a standard LeetCode 75 or Blind 75 LeetCode clone. We focus on the why and the when.

  • Pattern Recognition: Learn the specific triggers that indicate a problem can be solved with a particular pattern.
  • Optimal Approaches: Understand why a pattern works and how it improves upon brute-force solutions (often moving from O(n^2) to O(n) time complexity).
  • Avoiding Pitfalls: Learn the common mistakes and anti-triggers—knowing when not to use a pattern is just as important as knowing when to use it.
  • Structured Practice: Our roadmap is carefully sequenced. You build fundamental skills first, then move on to more complex patterns like Dynamic Programming and Graphs.

Who Benefits from Pattern Recognition?#

Our roadmap is designed for two main audiences:

  1. Coding bootcamp graduates & beginners: If you understand basic syntax but struggle to formulate an algorithm from scratch, learning patterns will bridge that gap. A coding bootcamp might teach you how to build an app, but we teach you how to pass the technical interview. You'll move from staring at a blank screen to having a concrete starting point.
  2. Experienced developers returning to practice: If you haven't interviewed in years and feel rusty, our structured path helps you quickly refresh your algorithmic thinking. You can use the challenge problems to test out of patterns you already know and focus on your weak areas.

How to Use Our Coding Roadmap#

We recommend progressing through the stages in order. Start with the Foundations (Linear Patterns) to understand how to optimize array and string traversals. Then move to Sorting, Linked Lists, and Trees.

For each pattern: 1. Read the conceptual explanation. 2. Note the signals (triggers) for the pattern. 3. Solve the carefully selected practice problems on standard platforms like LeetCode. We provide a curated list of teaching, consolidation, and challenge problems.

By the end of this journey, you won't just know how to write code; you'll know how to solve problems with confidence.

Frequently Asked Questions#

What are coding patterns?

Instead of memorizing hundreds of specific solutions, coding patterns (like Sliding Window, Two Pointers, or Fast & Slow Pointers) are reusable templates for solving common data structure and algorithm problems. Recognizing a pattern instantly reduces an unfamiliar problem from an unknown puzzle to a familiar structure.

How do I get better at LeetCode and technical interviews?

The secret isn't solving 1,000 random problems—it's learning to categorize them. If you want to know how to get better at LeetCode, the answer is structured practice. By focusing on one pattern at a time, you build intuition. When you face a new problem in a technical interview, you won't freeze; you'll actively look for "triggers" that tell you exactly which pattern to apply.

How many LeetCode problems should I do to prepare?

Quality matters far more than quantity. Solving 50 to 100 problems intentionally—by understanding the underlying patterns—will prepare you much better than grinding 500 problems blindly. Our roadmap curates the exact minimum effective dose (4 to 6 problems per pattern) needed to build true problem-solving fluency.

How should I prepare for a technical interview as a software engineer?

If you are preparing for a software engineering technical interview, start by mastering core data structures (arrays, hash maps, linked lists, trees, graphs). Once you know the structures, walk through our pattern roadmap sequentially. Learn the triggers for when to use a specific approach, and use our challenge problems to test your readiness.

Do I need LeetCode Premium to use this roadmap?

No! We know many learners wonder is LeetCode Premium worth it, but you do not need it to use PatternDojo. We intentionally select high-quality problems that are available for free on standard coding judges. Our goal is to make technical interview preparation accessible to everyone, from coding bootcamp grads to senior developers.