Coding & data structures
The patterns that actually appear in coding interviews, derived from first principles rather than memorised — each one with the invariant that makes it correct, the complexity argument that makes it fast, and runnable code you can edit.
Most candidates fail coding rounds not because they don't know binary search, but because they can't say why their loop terminates. This track builds the other half.
Foundations — reading the problem, and the three pointer patterns
Before any data structure: how to turn a vague prompt into a specification, how to reason about cost honestly, and the three linear-scan patterns that between them cover a large slice of every question bank.
-
1
Reading the problem
A coding interview is a specification exercise wearing an algorithms costume. This is the seven-minute routine that turns a two-sentence prompt into something you can actually solve — and the reason interviewers score it separately from your code. Free -
2
Complexity, honestly
Big-O as interviewers actually use it — what the notation is really claiming, why "amortised O(1)" is a mathematical statement and not a hand-wave, and the specific complexity claims candidates get wrong most often. Free -
3
The sliding window
Why a nested loop can be linear, stated as an invariant you can prove in one sentence — then the fixed-size, variable-size, and counting variants, each derived from the same monotonicity argument rather than memorised as three separate templates. Free -
4
Two pointers
The exchange argument that proves opposite-direction two pointers correct — why discarding a candidate is safe — plus the same-direction and fast/slow variants, and the cycle-detection result that looks like a magic trick until you see the algebra. Free -
5
Binary search, and why your version has a bug
Binary search is famously easy to get subtly wrong. The cure is a loop invariant instead of a remembered template — and once you have the invariant, "binary search on the answer" stops being a separate trick and becomes the same algorithm on a different array. Free
Hashing, counting, and prefix sums
The three structures that turn a quadratic scan into a linear one — a hash map that answers "have I seen this?", a counter that answers "how many?", and a prefix sum that answers "what is the total between here and there?" — each with the failure mode that bites in interviews.
-
1
Hash maps, from the inside
What a hash map actually does when you call get — open addressing versus chaining, why the load factor decides your constant, why insertion order is a language guarantee and not a coincidence, and the two ways an interviewer can make your "O(1)" claim false. 20 min · app -
2
Counting: frequency as state you can update
Why a frequency map beats sorting for almost every "compare these multisets" question, when to count into an array instead, how a count becomes incremental state that composes with a sliding window, and the two O(n) tricks — bucket-by-count and the majority vote — that a heap-shaped answer misses. 22 min · app -
3
Prefix sums and difference arrays
Precompute once, answer any range query in O(1) — the leading-zero convention that removes every off-by-one, the prefix-count map that solves subarray-sum problems a sliding window cannot touch, the difference array that makes range updates constant time, and the two dimensions where the same idea becomes inclusion–exclusion. 24 min · app -
4
Sets, canonical keys, and the seen-set invariant
Choosing the key is the design decision in most hashing problems — a sorted string versus a count signature for grouping, why an array can't be a key in JavaScript but a tuple can in Python, how a set turns an O(n log n) sequence problem into an amortised O(n) one, and the three cases where a set is the wrong structure entirely. 20 min · app
Linear structures — lists, stacks, queues, and intervals
Four structures that all look like "a line of things" and behave nothing alike: a linked list where the pointer is the data, a stack that lets you defer a decision until you have the information to make it, a queue whose obvious implementation is quietly O(n), and an interval list where the whole problem is the order you sort in.
-
1
Linked lists: pointer surgery you can trust
A linked list is the one structure where the pointer is the data, so every bug is an aliasing bug — this lesson builds the three routines every list question is assembled from (in-place reversal, the sentinel node, and the fast/slow pair), proves why Floyd's tortoise and hare must meet, and derives the cycle-start formula instead of memorising it. 26 min · app -
2
Stacks and queues: deferring a decision
A stack is not a container, it is a policy — "I can't decide about this item yet, so hold it until I can" — and once you read it that way, parentheses, expression evaluation, undo, and recursion are all one problem; queues are the mirror image, with one trap that costs real interviews, because the obvious array implementation of a queue is quadratic. 24 min · app -
3
Monotonic stacks and deques
One structure answers every "nearest larger element" question in linear time, and the reason is a single invariant — the stack holds only the indices whose answer is still undecided, in sorted order, because an element with a bigger neighbour behind it can never be anyone's answer again; this lesson derives that invariant, uses it on the histogram problem, and then adds a left boundary to get the sliding-window maximum. 26 min · app -
4
Intervals: sorting is the algorithm
Interval questions are hard for one reason — six ways two intervals can overlap, and code that enumerates them is unreadable and wrong — and they become easy for one reason: sorting collapses those six cases into one comparison, with the twist that merging wants them sorted by start and selection wants them sorted by end, for reasons you can prove. 24 min · app
Sorting and selection — order, and the parts of it you actually need
You will almost never implement a sort in an interview, and you will constantly decide whether to call one — so this module is about what the order buys you, what it costs, and the three situations where sorting is the wrong answer: when you only need the top k (a heap), when you only need the k-th (quickselect), and when the keys aren't comparisons at all (counting and radix).
-
1
Sorting: the invariant you are buying
Nobody will ask you to implement quicksort, and everybody will judge the comparator you write, the stability you assume, and whether you noticed that the O(n log n) you just added is now the dominant term — so this lesson treats sorting as a purchase: what invariant does the order give you, what does it cost, and when is the price wrong. 26 min · app -
2
Merging, and what divide-and-conquer actually costs
Merge sort is worth learning for one reason that has nothing to do with sorting — the merge step is a place to compute things, and once you see that, counting inversions, merging k sorted streams, and the whole "split, solve, combine" family stop being separate tricks and become one recurrence you can read off the code. 26 min · app -
3
Heaps: paying only for the order you need
A heap is the structure you get by giving up almost all of sorting's guarantees and keeping one — the extreme element is at the front — and that single retained guarantee is enough for top-k, k-way merge, running medians, schedulers, and Dijkstra, at O(log n) per update instead of a re-sort. 28 min · app -
4
Partitioning: quickselect, and the k-th without the order
One pass can put a pivot in its final position and split everything else into "smaller" and "larger" — and that single primitive gives you the k-th smallest element in expected linear time, sorts an array with three-way splits, solves the three-colour problem in one scan, and explains why every production quicksort is really three algorithms glued together. 28 min · app
Work through it with feedback
Reading the pattern is step one. The app runs you through it — editable code cells, the question bank, and a mock loop that grades your answer.
Open the curriculum in ChannelPulse