Asymptotic notation
Big-O is the upper bound, Big-Omega the lower, Big-Theta the tight one. Interviews ask for O but mean Theta. Constants and lower-order terms drop because they stop mattering as n grows.
External Big-O notationAll stages, in order — from Big-O through advanced trees, graph algorithms, dynamic programming, and the interview patterns that tie them together. The complete spine. Each topic links to a Semicolony deep dive or simulator where one exists, and to a curated external resource where it doesn't. Follow the arc in order, or jump to wherever you're stuck.
Core plus the recommended layer. The optional stops stay hidden until you have shipped a couple of real systems.
The vocabulary the rest of this roadmap is written in.
Before any structure or algorithm makes sense, you need to reason about cost. Big-O is how engineers compare approaches without running them — the difference between an answer that scales and one that falls over at 10x load.
Big-O is the upper bound, Big-Omega the lower, Big-Theta the tight one. Interviews ask for O but mean Theta. Constants and lower-order terms drop because they stop mattering as n grows.
External Big-O notationYou almost always buy speed with memory and vice versa. A hash map turns an O(n) scan into O(1) by spending O(n) space. Knowing which side you can afford to spend is half of senior problem-solving.
Problem-solvingO(1), O(log n), O(n), O(n log n), O(n²), O(2ⁿ), O(n!). Memorise the shape of each curve. The jump from n log n to n² is where most naive solutions quietly die.
Sim Big-O raceA dynamic array resize is O(n), but it happens so rarely that pushes average out to O(1). Amortised cost is the honest per-operation price over a sequence — not the worst single call.
External Amortised analysisContiguous memory and the patterns it unlocks.
Arrays are the bedrock — contiguous memory with O(1) indexing, the structure every other one is measured against. Strings are arrays of characters with their own gotchas. Master the two-pointer and sliding-window moves here and a third of interview problems collapse.
A fixed array is a block of memory; a dynamic array (vector, list, slice) doubles and copies when it fills. Indexing is O(1), insert-in-middle is O(n) because everything after shifts.
Data structures explorerWalk one index from each end (or two at different speeds) to turn an O(n²) nested loop into O(n). Pair sums, palindrome checks, and partitioning all fall to it on a sorted array.
Problem-solvingMaintain a window over a contiguous range and slide it instead of recomputing. Longest-substring and max-subarray-of-size-k problems go from O(n·k) to O(n) once you stop re-summing.
Problem-solvingPrecompute running totals once and any range sum becomes O(1). A difference array does the inverse for range updates. Both turn repeated range queries from quadratic to linear.
External Prefix sumPattern matching (KMP, Rabin-Karp) finds a needle in O(n+m) instead of O(n·m). Strings are immutable in many languages, so naive concatenation in a loop is a hidden O(n²) trap.
External String searchingO(1) lookups — until the collisions show up.
A hash map is O(1) until it isn't — collisions, resizing, and a bad hash turn it into a linked list. Understanding what happens under the hood is the difference between using a map and trusting it under load.
A good hash spreads keys uniformly across buckets and is fast to compute. A bad one clusters everything into a few slots and your O(1) map degrades to an O(n) scan.
How hash tables workTwo keys, one bucket. Chaining hangs a list off each slot; open addressing probes for the next free one. Both keep lookups near O(1) — until the load factor climbs and you must resize.
How hash tables workThe single highest-leverage interview structure. Most "find the duplicate / two-sum / group anagrams" problems are a hash map in disguise — trade O(n) space to drop a dimension off the time.
Problem-solvingA probabilistic set that says "definitely not present" or "probably present" using a fraction of the memory. No false negatives, tunable false positives. The trick behind cache and DB membership checks.
Sim Bloom filterPointer-chasing, and the last-in and first-out structures.
Linked lists trade O(1) indexing for O(1) insertion anywhere — and force you to think in pointers. Stacks and queues are restricted lists whose discipline (LIFO, FIFO) is exactly what half of recursion, parsing, and scheduling needs.
No contiguous memory, so no O(1) indexing — you chase pointers. But insert and delete at a known node are O(1) with no shifting. Reversing one in place is the classic pointer-juggling interview.
Sim Linked listPush and pop from one end. The call stack, undo history, balanced-parens checking, and DFS are all stacks. When a problem says "most recent first," reach for one.
Sim Queue & stackEnqueue at the back, dequeue at the front. BFS, task scheduling, and producer/consumer pipelines all run on queues. A deque opens both ends; a priority queue reorders by rank.
Sim Queue & stackA fixed-size queue that wraps around with head/tail indices and zero allocation per op. The structure behind audio buffers, log pipelines, and lock-free producer/consumer hand-offs.
How ring buffers workFloyd's tortoise-and-hare finds a cycle, the middle node, or the kth-from-end in one pass with O(1) space. The canonical linked-list trick that looks like magic until you see why it works.
Sim Linked listHierarchy, recursion, and ordered search.
Trees are where recursion stops being abstract. A binary search tree gives O(log n) lookup when balanced — and O(n) when it degenerates into a list. Traversals are the muscle memory every tree problem builds on.
Pre-order, in-order, post-order, level-order — four ways to visit every node, each suited to a different job. In-order on a BST yields sorted output; level-order is just BFS with a queue.
Sim BFS & DFS traversalLeft subtree smaller, right subtree larger, recursively. That invariant gives O(log n) search, insert, and delete — but only while the tree stays balanced. Insert sorted data and it degrades to a linked list.
Data structures explorerHeight, diameter, lowest common ancestor, path sums — almost every tree question is one recursive definition plus a base case. Frame it as "what does this node need from its children?"
Problem-solvingFlatten a tree to a string and rebuild it exactly. The encode/decode pair tests whether you really understand traversal order — and it is a stealthy way to ask about both DFS and BFS at once.
Problem-solvingAlways pulling the next-best item, in log time.
A heap is a tree that keeps the min (or max) at the root and rebalances in O(log n). When a problem needs "the k largest," "the next event," or "merge n sorted streams," it almost always wants a heap.
A complete binary tree stored flat in an array — parent at i, children at 2i+1 and 2i+2. Insert and extract-min are O(log n) by sifting up or down. No pointers, perfect cache behaviour.
Sim HeapThe abstract operation set — insert with a priority, pop the highest — that a heap implements. Dijkstra, Huffman coding, and event simulation all sit on top of one.
Sim HeapKeep a heap of size k and you find the k largest of a stream in O(n log k) without sorting everything. The standard answer to "top trending items" with bounded memory.
Problem-solvingBuild a heap in O(n) (not n log n — the math surprises people), then extract-min n times for an in-place O(n log n) sort. Not as cache-friendly as quicksort, but worst-case guaranteed.
External HeapsortSelf-balancing, disk-friendly, and special-purpose.
A plain BST is a coin flip on performance. The structures here guarantee O(log n) by rebalancing on every write — and others (tries, segment trees, B-trees) trade generality for being unbeatable at one specific job.
A BST that colours nodes and rotates on insert/delete to stay within 2× of perfectly balanced. The structure behind most language standard-library ordered maps and sets.
Sim Red-black treeFat, shallow trees where each node holds many keys to match a disk page. Fewer levels means fewer disk seeks — which is why every relational database index is a B+ tree.
Sim B-treeA tree keyed on shared prefixes so lookups cost O(length of key), independent of how many keys you store. Autocomplete, IP routing, and spell-check all run on tries.
Sim Trie autocompleteRange-sum or range-min queries with point updates, both in O(log n). When you need "sum of indices i..j" thousands of times with mutations between, a prefix array can't keep up — this can.
Sim Segment treeNodes, edges, and the two ways to walk them.
Once a problem mentions connections — friends, dependencies, roads, states — it is a graph. Pick a representation, then BFS or DFS. Most "graph" interview questions are really one of those two traversals wearing a costume.
Adjacency list for sparse graphs (most real ones), adjacency matrix for dense or constant-time edge checks. Choosing wrong turns an O(V+E) algorithm into O(V²) wasted space.
Data structures explorerA queue-driven level-by-level sweep. On an unweighted graph it finds the shortest path for free — the first time you reach a node is the fewest hops away. Flood fill and shortest-hops both live here.
Sim BFS & DFS traversalRecursion (or an explicit stack) plunging down one path before backtracking. Cycle detection, connected components, and topological sort all ride on DFS's entry/exit timing.
Sim BFS & DFS traversalOrder a DAG so every edge points forward — the only valid build, scheduling, or dependency-resolution order. Kahn's algorithm uses in-degrees and a queue; DFS uses post-order. Either detects cycles for free.
Problem-solvingDisjoint-set with path compression and union by rank answers "are these two connected?" in near-O(1) amortised. The engine behind Kruskal's MST and dynamic-connectivity problems.
External Disjoint-setWeighted edges, flow, and the named classics.
Add weights to edges and traversal becomes optimisation. These are the algorithms with names attached — Dijkstra, Bellman-Ford, A*, max-flow — each with a precise contract about what it assumes and what it costs.
Greedy shortest path on non-negative weights using a priority queue — O((V+E) log V). It fails the moment an edge goes negative, which is exactly the question a good interviewer asks next.
Sim Dijkstra pathfindingDijkstra plus a heuristic that biases the search toward the goal. With an admissible heuristic it is still optimal but explores far fewer nodes — the workhorse of game and map pathfinding.
Sim A* pathfindingSlower than Dijkstra at O(V·E), but it handles negative weights and detects negative cycles. The honest answer when Dijkstra's non-negative assumption doesn't hold.
External Bellman–Ford algorithmConnect every node at minimum total edge cost. Kruskal sorts edges and uses union-find; Prim grows from a seed with a heap. The classic answer to "cheapest network that reaches everyone."
External Minimum spanning treeThe most-studied algorithms, and why they still matter.
You will rarely write a sort by hand — but knowing why quicksort is usually fastest, when merge sort wins, and how binary search's off-by-one bugs hide is exactly what separates someone who uses the library from someone who understands it.
Merge sort (stable, O(n log n) guaranteed, needs space), quicksort (fast in practice, O(n²) worst case), heapsort (in-place, no worst-case blowup). Each wins under different constraints.
Sim Sorting visualizerNo comparison sort can beat O(n log n) — it is a proven floor, not a missing optimisation. Knowing why lets you recognise when a problem secretly needs sorting and accept the cost.
External Comparison sortHalve the search space each step for O(log n) — but only on sorted data, and the boundary conditions are a graveyard of off-by-one bugs. "Search on the answer" generalises it to any monotonic predicate.
Sim Binary searchCounting, radix, and bucket sort beat the n log n floor by exploiting structure in the keys — O(n) when the value range is bounded. The escape hatch when you know your data fits.
External Radix sortSolving a problem by assuming the smaller case is done.
Recursion is the art of defining a problem in terms of itself plus a base case. Backtracking is recursion that explores choices and unwinds dead ends — the brute-force engine behind permutations, sudoku, and the N-Queens board.
Every recursive call pushes a frame; the base case is what stops the stack from overflowing. See the frames pile up and the abstraction stops being scary — it's just a stack you didn't manage by hand.
Sim RecursionTry a choice, recurse, and undo it if it leads nowhere. Subsets, permutations, combinations, and constraint puzzles all share the same choose / explore / un-choose skeleton.
Problem-solvingPlace N queens so none attack — the textbook backtracking problem. Pruning illegal placements early is what turns an astronomical search into something that finishes. Watch the board prune itself.
Sim N-Queens backtrackingWhen the recursive call is the last thing a function does, it can become a loop with no stack growth. Knowing the conversion saves you from stack overflows on deep inputs.
External Tail callCache subproblem results and exponential recursion collapses to polynomial. It is the bridge from naive recursion to dynamic programming — same recurrence, just stop recomputing.
Sim DP: longest common subsequenceOverlapping subproblems, each solved only once.
DP is the topic that breaks the most candidates — and the one that yields entirely once you see it as "recursion with a memo." The whole skill is spotting overlapping subproblems and defining a state that captures everything you need.
Top-down caches recursive calls; bottom-up fills a table in dependency order. Same recurrence, two implementations — tabulation avoids stack depth, memoisation only computes states you actually reach.
Sim DP: longest common subsequenceThe whole game. What does dp[i] mean, and how does it build from smaller states? Get the state definition right and the code is trivial; get it wrong and no amount of debugging helps.
Problem-solvingClimbing stairs, house robber, coin change, longest increasing subsequence. One array, one dimension of state. The on-ramp where you learn to read the recurrence off the problem.
Problem-solvingEdit distance, longest common subsequence, grid paths, knapsack. Two indices, a table you fill row by row. The simulator makes the table-filling order click in a way text never does.
Sim DP: longest common subsequenceWhen grabbing the local best, or splitting in half, works.
Greedy takes the best-looking option at each step and hopes it adds up — sometimes provably optimal, often a trap. Divide-and-conquer splits, solves, and merges. Both are powerful precisely because they avoid exploring everything DP does.
Interval scheduling, Huffman coding, and coin change (with the right coins) all fall to a greedy choice. The hard part is proving the local optimum is global — and noticing when it isn't.
Problem-solvingGreedy is fast but fragile. 0/1 knapsack and general coin systems break it — the only fix is the exhaustive search DP gives you. Recognising the failure is more valuable than the algorithm itself.
External Knapsack problemSplit the problem in half, solve each recursively, combine. Merge sort, quicksort, and binary search are all this pattern — and the Master Theorem reads off their cost without tracing the recursion.
External Divide-and-conquerMerge overlapping ranges, find free slots, schedule the most meetings. Sort by start or end, then sweep — a greedy template that covers a surprising slice of the interview canon.
Problem-solvingSpotting the familiar shape in an unfamiliar problem.
Senior performance is pattern recognition. Once you have the structures and algorithms, the last skill is matching an unfamiliar problem to a known technique in the first ninety seconds — then communicating the trade-offs as you code.
Two pointers, sliding window, fast/slow, BFS/DFS, top-k heap, backtracking, DP. Maybe fifteen patterns cover the overwhelming majority of interview problems. Drilling them is higher-leverage than grinding random questions.
Problem-solvingRestate the problem, name the constraints, find the brute force, then optimise. The structured approach that keeps you moving when you don't instantly see the trick — and shows the interviewer how you think.
Problem-solvingThe interview is graded on signal, not just a passing test. Narrate the approach, call out the complexity, test your own edge cases out loud. A silent correct answer scores below a narrated one.
Interview hubSpaced repetition over patterns beats random grinding. Redo the ones you missed a week later; if you can't re-derive it, you memorised the answer, not the technique.
External NeetCode roadmapEmpty input, single element, duplicates, overflow, the maximum-size case. Stating the time and space cost — and the cases that break naive code — before you're asked is a senior tell.
Sim Big-O raceBackend, system design, frontend, DevOps, security, DSA and data — the full set, in one place.
OpenSorting, B-trees, Dijkstra, DP, recursion, hashing — watch the algorithms run.
OpenA cabinet of shapes, each with operations and Big-O.
OpenTime-boxed practice rounds and concept flashcards.
Open