DSA Patterns
Most interview questions are variations of a small set of patterns. Each pattern below has fully worked questions — the problem explained with an example, more than one approach, and a dry run of the solution — plus extra practice links on LeetCode and GeeksforGeeks.
Reading up on the concepts first? Follow the Learn DSA path — it covers the theory behind these patterns in order.
0 of 26 questions solved
Progress is saved in your browser.
Two Pointers
Walk two indexes toward each other (or in the same direction) instead of checking every pair — turns many O(n²) array problems into O(n).
How to spot it: Sorted array or string, and the question asks about pairs, triplets, or removing/comparing elements from both ends.
The cleanest introduction to two pointers — use the sorted order to walk in from both ends instead of checking every pair.
Fix one number, then run Two Sum II on the rest — plus the duplicate-skipping trick that trips everyone up the first time.
Sliding Window
Maintain a window over a contiguous run of elements and slide it forward, updating state incrementally instead of recomputing from scratch.
How to spot it: The words “subarray”, “substring”, or “contiguous” appear, and you need a longest / shortest / max-sum window that satisfies a condition.
The canonical fixed-size window: slide by adding one element and removing another, instead of re-summing k elements every time.
The classic variable-size window: grow the right edge greedily, shrink the left edge only when a character repeats.
Fast & Slow Pointers
Two pointers moving at different speeds through a sequence — if there is a cycle they must eventually meet, and when the fast one finishes, the slow one is at the middle.
How to spot it: Linked list problems about cycles or middles, or any process that repeatedly feeds a value back into itself.
Floyd's tortoise and hare — detect a cycle with two pointers and zero extra memory, instead of remembering every node you've seen.
Fast & slow pointers without a linked list — any process that feeds a value back into itself forms an implicit chain you can cycle-detect.
Merge Intervals
Sort intervals by start time, then sweep left to right deciding whether each interval overlaps the previous one — merge, count, or discard as you go.
How to spot it: Input is a list of ranges (meetings, bookings, [start, end] pairs) and the question is about overlap, merging, or how many fit.
Sort by start, then one linear sweep: each interval either extends the last merged one or starts a new group.
Interval scheduling in disguise — sort by end time and greedily keep the interval that frees up the timeline soonest.
Binary Search
Halve the search space every step. Works on sorted arrays — and, more powerfully, on any monotonic “answer space” where you can ask: is this guess feasible?
How to spot it: Sorted input, O(log n) required, or a “minimum X such that condition holds” question where the condition flips from false to true exactly once.
The template everything else builds on — get the loop condition, midpoint, and boundary updates right once, and reuse them forever.
Binary search on the answer, not the array — when a yes/no condition flips from false to true exactly once, you can search the answer space.
Stack & Monotonic Stack
Last-in-first-out matching for nested structure, and the monotonic variant: keep the stack sorted so each element instantly finds its “next greater / smaller” partner.
How to spot it: Matching brackets, undo-like nesting, or “next greater element” / “how long until a warmer day” style questions.
The purest stack problem: every closer must match the most recently opened bracket — last in, first out.
The monotonic stack in its natural habitat — every 'next greater element' question is this problem wearing a costume.
Heap / Top-K
A heap always knows its smallest (or largest) element in O(1). Keep a heap of size k while streaming through data to answer “top k” questions without full sorting.
How to spot it: The words “k largest”, “k closest”, “k most frequent”, or a stream where you repeatedly need the current min/max.
Keep a min-heap of the k largest seen so far — the heap's smallest element is always your current answer.
Count with a map, then pick the top k — by sorting, by heap, or in O(n) with the bucket trick.
Tree BFS / DFS
Depth-first recursion for structure questions (depth, validity, paths); breadth-first with a queue for anything organized by levels.
How to spot it: Binary tree input. “Level by level” means BFS; “depth”, “path”, or “is it valid” usually means DFS.
The template for every level-by-level tree question: a queue, plus the level-size snapshot trick.
The classic trap: checking each node against its children isn't enough — you must carry min/max bounds down the tree.
Graph Traversal
BFS/DFS over grids and adjacency lists: flood-fill connected regions, count components, and use topological ordering when tasks have prerequisites.
How to spot it: A grid of cells, a list of edges, or dependency pairs (“course a requires course b”). Count regions, check reachability, or order tasks.
The grid is a graph in disguise — flood-fill each unvisited land cell and count how many times you had to start.
Prerequisites form a directed graph — you can finish all courses exactly when that graph has no cycle. Enter topological sort.
Backtracking
Build a candidate solution one choice at a time; when a choice can no longer lead to a valid answer, undo it and try the next one. The shape behind subsets, permutations, and puzzles.
How to spot it: “All possible …” — combinations, permutations, subsets, board placements — where you must enumerate rather than count.
The hello-world of backtracking: at each element, branch on include vs. exclude — and learn why you push, recurse, then pop.
Backtracking with pruning and unlimited reuse — and the start-index trick that kills duplicate combinations.
Dynamic Programming
When a problem breaks into overlapping subproblems, solve each subproblem once and reuse the answer — top-down with memoization or bottom-up with a table.
How to spot it: “How many ways…”, “minimum cost to…”, “longest/shortest …” where today’s answer is built from smaller versions of the same question.
The gateway DP problem — watch naive recursion explode, then fix it with memoization, a table, and finally two variables.
The problem that teaches why greedy fails and how to build a bottom-up DP table over amounts — plus the unreachable-state trick.
Math & Number Theory
A small toolbox — Euclid’s GCD, the sieve of Eratosthenes, fast exponentiation, counting prime factors — that solves a surprising number of interview questions outright.
How to spot it: Primes, divisibility, powers, factorials, digit manipulation — anywhere brute-force arithmetic would overflow or time out.
Checking each number for primality is too slow — the 2,300-year-old sieve crosses out composites in near-linear time.
Multiplying x by itself n times is O(n) — squaring your way there is O(log n), the same halving idea as binary search.
The oldest algorithm still in daily use — replace the bigger number with a remainder until one hits zero.
You can't compute 100! — but you don't need to. Trailing zeros come from factors of 5, and you can count those directly.