Data structures and algorithms, from nothing.
Twenty-four lessons that start at “what does O(n) mean” and end with you solving the questions Google, Meta and Amazon actually ask. Every example runs on this page, so nothing has to be taken on trust.
- 24 lessons
- 6h 50m of reading
- 16 patterns, 96 problems
- No install, works offline
The thing being taught
Here is one problem solved twice. Both answers are correct. One of them is the reason candidates fail interviews, and by lesson 06 the difference will be obvious to you on sight.
// Find the longest run of characters with no repeats. "abcabcbb" -> 3 ("abc")
let bruteSteps = 0, windowSteps = 0;
// Attempt one: check every substring. Correct, and unusably slow.
function longestBrute(s) {
let best = 0;
for (let start = 0; start < s.length; start++) {
for (let end = start; end < s.length; end++) {
bruteSteps++;
const piece = s.slice(start, end + 1); // O(length) itself
if (new Set(piece).size === piece.length) best = Math.max(best, piece.length);
}
}
return best;
}
// Attempt two: one pass. A window that grows on the right and shrinks on the
// left, and a map remembering where each character last appeared.
function longestWindow(s) {
const lastSeen = new Map();
let best = 0, left = 0;
for (let right = 0; right < s.length; right++) {
windowSteps++;
const ch = s[right];
// If this character is already inside the window, jump the left edge past
// it. Never backwards: that is what keeps the whole thing linear.
if (lastSeen.has(ch) && lastSeen.get(ch) >= left) left = lastSeen.get(ch) + 1;
lastSeen.set(ch, right);
best = Math.max(best, right - left + 1);
}
return best;
}
// Both agree on every input, including the awkward ones.
for (const input of ['abcabcbb', 'bbbbb', 'pwwkew', '', 'dvdf']) {
console.log(`"${input}" -> brute ${longestBrute(input)}, window ${longestWindow(input)}`);
}
// Now count the work as the input grows.
console.log('\n n brute steps window steps ratio');
for (const n of [100, 200, 400, 800]) {
const input = Array.from({ length: n }, (_, i) => 'abcdefghij'[i % 10]).join('');
bruteSteps = 0;
windowSteps = 0;
const a = longestBrute(input);
const b = longestWindow(input);
if (a !== b) throw new Error('the two disagree, which would be a bug');
console.log(
String(n).padStart(4),
String(bruteSteps).padStart(14),
String(windowSteps).padStart(14),
(bruteSteps / windowSteps).toFixed(0).padStart(11) + 'x'
);
}
console.log('\nDouble n: the window does twice the work, brute force four times.');
console.log('And each brute step costs more too, because slicing is not free.');
console.log('That gap is what Big-O measures, and it is lesson 01.');
Output
Part one — Foundations
Complexity, the core structures, and the first techniques. Read these in order.
- 01 How Fast Is Fast: Big-O Without the Maths Read any function and say its time and space complexity out loud. 16 min
- 02 Arrays: the One You Already Use Predict the cost of any array operation before you write it. 14 min
- 03 Strings Manipulate strings without accidentally writing O(n squared) code. 12 min
- 04 Hash Maps and Sets Trade memory for speed using a Map or a Set. 17 min
- 05 Two Pointers Replace a nested loop with two indices moving in one pass. 15 min
- 06 Sliding Window Solve any contiguous-subarray question in one pass. 17 min
- 07 Prefix Sums and Counting Answer range-sum questions in O(1) after an O(n) setup. 14 min
- 08 Linked Lists Reverse, merge and detect cycles in a linked list without losing your place. 18 min
- 09 Stacks Recognise when a problem is secretly asking for a stack. 15 min
- 10 Queues and Deques Build an O(1) queue and use a deque to keep a running maximum. 14 min
- 11 Recursion and the Call Stack Write and trace a recursive function without guessing. 18 min
- 12 Binary Search Write binary search from memory, including searching on the answer. 19 min
- 13 Sorting Implement merge sort and quicksort, and sort correctly with the built-in. 17 min
- 14 Trees and Traversals Traverse a tree four ways, recursively and iteratively. 19 min
Part two — The heavy machinery
Trees, graphs, recursion-based search, and dynamic programming.
- 15 Binary Search Trees Search, insert and validate a BST, and explain why balance matters. 15 min
- 16 Heaps and Priority Queues Write a heap from scratch and use it for top-k problems. 20 min
- 17 Graphs, BFS and DFS Represent a graph and traverse it breadth-first and depth-first. 21 min
- 18 Topological Sort, Union-Find and Dijkstra Order dependencies, group connected things, and find cheapest paths. 22 min
- 19 Backtracking Generate every valid arrangement with one recursive template. 20 min
- 20 Dynamic Programming Turn a slow recursion into a memoised, then tabulated, solution. 26 min
- 21 Greedy Algorithms Spot when greedy is provably correct and when it is a trap. 15 min
- 22 Intervals Merge, insert and schedule intervals correctly. 14 min
- 23 Grids and Matrices Flood-fill, rotate and traverse a matrix without index errors. 17 min
- 24 Bit Manipulation Use XOR, masks and shifts, and know where JavaScript surprises you. 15 min
Nothing marked done yet. Lesson 01 is a good place to start.
What you are actually being tested on
A technical interview is not a memory test, though it is often mistaken for one. Four things are being assessed, and only the last one is about knowing algorithms.
Recognition
Reading a problem and knowing, within a minute, which of about sixteen shapes it is. “Sorted array, find a pair” is two pointers. “Contiguous subarray” is a sliding window. “Shortest path in an unweighted graph” is breadth-first search. This is the single highest-value skill and it is trainable.
Every lesson, then Patterns
Cost
Saying what your solution costs in time and space, without hedging, and knowing whether that is good enough for the constraints you were given. An O(n²) answer to a problem with n = 100000 is a wrong answer.
Lessons 01, 12, 20, then Complexity
Correctness under pressure
Code that runs on the first try, including the empty input, the single element, and the duplicate. Most candidates who fail were on the right track and got the boundary wrong.
Lessons 02, 12, 22, then The interview
Thinking out loud
A silent candidate with a working answer scores below a talking candidate with a partial one, because the interviewer is grading your reasoning and cannot see it otherwise. This is a habit, not a talent, and it has to be practised deliberately.
How to work through it
The order matters. Lessons 01 to 07 are one continuous argument: what cost means, then the two structures that everything is built from, then the three techniques that turn a nested loop into a single pass. Skipping ahead to graphs before that lands is the most common way to waste a month.
- Read one or two lessons a day with this page open in one window and your editor in the other.
- Run every panel. When the output surprises you, change a line and run it again. That is the entire study method, and it is why the examples are executable rather than printed.
- Do the task at the foot of each lesson before moving on. Editable panels keep what you type in this browser, so you can leave one half-finished.
- After lesson 14, start mixing in problems. Do not wait until you have finished the course; recognition only develops on unfamiliar problems.
- When something will not stick, write it out from memory on paper. The templates page is the target to reproduce, not to read.
How long this honestly takes
The reading is 6 hours. Becoming good enough to pass a big-tech loop is closer to two to three months at an hour or two a day, and the ratio that matters is roughly one part reading to four parts solving problems without help. The roadmap lays out eight weeks of that, but treat the dates as a shape rather than a promise: what determines the outcome is the number of problems you have worked through where you did not already know the answer.
Everything else
The 16 patterns that cover most interview questions, each with the signal that tells you to reach for it.
Problem set96 curated problems grouped by pattern, each with hints and a tested solution you can run.
RoadmapAn eight-week plan, plus what to do in the last 48 hours before an interview.
The interviewHow to run the 45 minutes: clarifying, thinking aloud, coding, testing, and what interviewers score.
Complexity tablesEvery structure and operation, with its real cost. Printable.
TemplatesCopy-paste starting points for binary search, BFS, DFS, heaps, union-find, backtracking and DP.
PlaygroundA blank editor with the runner attached, and helpers for building trees, lists and graphs.
GlossaryEvery term in the course in plain language.
What this is, honestly
A course written to be read offline. There is no account, no backend, no analytics and no network request of any kind; the fonts are inlined into the stylesheet and the syntax highlighter is a few hundred lines in assets/js/highlight.js. Your progress and anything you type into an editable panel are kept in this browser's localStorage under the dsa. prefix and nowhere else, so clearing site data clears them.
Code in a panel runs in your own browser, inside a function scope with a shadowed console, always under "use strict", with a loop guard that stops a runaway while rather than hanging the tab. That is what makes the examples honest, and it also means an editable panel will run whatever you paste into it. Treat it the way you would treat your own devtools console.
Problems are described in my own words and linked by number rather than reproduced, so the wording here will differ from the original site. Where a problem has a well-known name it is given, so you can find it.