Sixteen patterns, sixty-one worked problems. Every problem gets a full Python solution, a line-by-line explanation, a complexity account, and the edge cases an interviewer will probe.
Most coding interview questions are not new problems. They are one of a small number of shapes wearing a new costume. Learn to see the shape and the code writes itself. This site takes the sixteen shapes that cover the large majority of questions, explains when to reach for each one and why the trick works, then works through the canonical problems in Python.
16 of 16 patterns written · 61 problems solved · 4 guides.
Not patterns. The mechanics around them, and the fastest way to raise a score without learning another algorithm.
What each operation costs, the five modules that matter, and the traps that quietly turn O(n) into O(n²).
Read the constraint list as a hint. Input size maps to expected complexity, and several phrasings name a pattern outright.
Seven phases, a time budget, what to say when stuck, and a worked transcript from clarify to close.
Dry-run tables, five boundary checks, edge cases by input type, and a worked bug hunt on a real solution.
A contiguous run in an array or string, and you want the longest, shortest or best one.
A sorted array, and you need a pair, a triplet, or an in-place compaction.
A linked list or an implicit sequence, and you suspect a cycle or need the midpoint.
Time ranges or numeric ranges that overlap, and you need them merged, counted or trimmed.
Numbers drawn from a bounded range, and you must find what is missing or duplicated in O(1) space.
Pointer surgery on a linked list with no extra memory allowed.
Level-by-level processing, or the shortest path in an unweighted graph.
Explore every path, compute something bottom-up, or flood-fill a region.
The K best, worst or most frequent items, from a large or streaming dataset.
Enumerate every combination, permutation or arrangement, pruning the dead ends.
Anything with a monotone yes/no boundary, sorted or rotated, in O(log n).
An optimal value or a count of ways, built from overlapping subproblems.
Range sums where a sliding window fails: negative values, exact targets, or divisibility.
For each element, the nearest larger or smaller one, and how far it reaches.
Ordering under dependencies, and detecting when no valid order exists.
Connectivity on a graph whose edges keep arriving, where re-running DFS is too slow.
| What the question says | Reach for |
|---|---|
| “contiguous subarray”, “substring”, “window of size k” | Sliding Window |
| “sorted array” plus “pair / triplet / sum to target” | Two Pointers |
| “cycle”, “middle of the list”, “repeats forever” | Fast and Slow Pointers |
| “intervals”, “meetings”, “start and end times” | Merge Intervals |
| “array of n numbers in range 1..n”, “missing”, “duplicate” | Cyclic Sort |
| “reverse the list”, “in place”, “O(1) extra space” | List Reversal |
| “level by level”, “minimum number of steps”, “nearest” | BFS |
| “all paths”, “connected region”, “does a path exist” | DFS |
| “top K”, “K most frequent”, “K closest”, “median of a stream” | Heaps |
| “all subsets”, “all permutations”, “place N things without conflict” | Backtracking |
| “sorted”, “rotated”, “first index where…”, “minimise the maximum” | Binary Search |
| “how many ways”, “minimum cost”, “longest subsequence” | Dynamic Programming |
| “subarray sums to exactly k”, “values may be negative”, “divisible by k” | Prefix Sum |
| “next greater”, “span”, “histogram”, “how far until something taller” | Monotonic Stack |
| “prerequisites”, “build order”, “can all tasks be finished” | Topological Sort |
| “connected components”, “edges arrive one at a time”, “merge groups” | Union-Find |
The short list. The full table, with the traps that go with it, is in Guide 1.
| Operation | Time | Note |
|---|---|---|
| List index, append | O(1) | Append is amortised; a resize is occasional. |
| List insert or pop at index 0 | O(n) | Use collections.deque instead. |
deque.popleft() / appendleft() | O(1) | The queue for BFS. |
| Dict or set lookup, insert, delete | O(1) | Average. Worst case O(n) on adversarial hashes. |
sorted() / list.sort() | O(n log n) | Timsort. Stable, and O(n) on already-sorted input. |
heapq.heappush / heappop | O(log n) | Min-heap only. Negate values for a max-heap. |
heapq.heapify | O(n) | Cheaper than n pushes. |
| String concatenation in a loop | O(n²) | Build a list and "".join() it. |
Slicing a[i:j] | O(j - i) | It copies. Easy to hide a quadratic loop this way. |
x in list / x in set | O(n) / O(1) | The single most common accidental slowdown. |