Emmanuel Akinfulubi

Complexity tables

Every cost in the course, in one place. Written to be printed — the header, footer and controls drop out when you do.

Two things are worth saying before the numbers. First, complexity describes how cost grows, not how fast something is; an O(n²) algorithm can beat an O(n log n) one on small input, and often does. Second, in an interview you should state both time and space without being asked. Volunteering “this is O(n log n) time and O(n) space because the merge needs a buffer” reads as fluency in a way that answering the question afterwards does not.

Growth rates

How fast each class of algorithm grows. Assume roughly 10⁸ simple operations per second.
Complexityn = 10n = 1,000n = 100,000n = 10,000,000Verdict
O(1)1111Instant, always
O(log n)3101723Instant, always
O(n)101,000100,00010,000,000Fine
O(n log n)3310,0001.7 million230 millionFine, the sorting bound
O(n²)1001 million10 billion—Fine to about n = 10,000
O(n³)1,0001 billion——Only to about n = 500
O(2ⁿ)1,024———Only to about n = 25
O(n!)3.6 million———Only to about n = 11

Reading the constraints

The problem statement usually tells you the intended complexity, if you know how to look. This table is the single most useful thing on this page during a timed interview.

Read the constraints backwards: the size of n tells you which complexity is being asked for.
If n is up toThe intended solution is probablyWhich usually means
10–12O(n!)Permutations, brute-force ordering
15–20O(2ⁿ) or O(2ⁿ × n)Subsets, bitmask DP, travelling-salesman shapes
100O(n³)Floyd–Warshall, interval DP, triple loops
1,000–5,000O(n²)Two-sequence DP, all-pairs comparison
10⁵ to 10⁶O(n log n)Sorting, heaps, binary search on the answer
10⁷ and aboveO(n) or O(log n)One pass, two pointers, sliding window, hashing, maths

Arrays

Arrays. The three marked in red are the ones that quietly turn a linear algorithm quadratic.
OperationCostNote
arr[i] read or writeO(1)Direct index arithmetic
push / popO(1)Amortised; an occasional resize is O(n)
shift / unshiftO(n)Every element moves. Use an index or a deque instead
splice(i, k)O(n)Shifts the tail
slice / spread [...a]O(n)A copy. Innocuous-looking inside a loop, and fatal
indexOf / includesO(n)Use a Set if you do this repeatedly
sortO(n log n)Mutates in place, and stable since ES2019
concat / join / map / filterO(n)Each allocates a new array or string
reverseO(n)In place
new Array(n).fill(x)O(n)The standard way to preallocate

shift() versus a head index

// The same BFS, two ways. Count the work each one does.
function bfsShift(n) {
  const queue = [0];
  let steps = 0, seen = 1;
  while (queue.length) {
    const node = queue.shift();       // O(n): every remaining element moves
    steps += queue.length + 1;         // the shift itself costs this much
    if (seen < n) { queue.push(seen++); queue.push(seen++); }
  }
  return steps;
}

function bfsIndex(n) {
  const queue = [0];
  let steps = 0, seen = 1, head = 0;
  while (head < queue.length) {
    head++;                            // O(1): nothing moves
    steps += 1;
    if (seen < n) { queue.push(seen++); queue.push(seen++); }
  }
  return steps;
}

console.log('  n     shift()      head index     ratio');
for (const n of [100, 400, 1600]) {
  const a = bfsShift(n), b = bfsIndex(n);
  console.log(String(n).padStart(4), String(a).padStart(11), String(b).padStart(14), (a / b).toFixed(1).padStart(9) + 'x');
}
console.log('\nThe ratio grows in step with n: quadruple n, quadruple the ratio.');
console.log('That is the extra factor of n that shift() smuggles in.');

Output


      

Maps, sets and objects

Maps, Sets and objects. Average case; hashing has a real constant factor.
OperationMap / SetPlain objectNote
InsertO(1)O(1)Average. Worst case is O(n) under adversarial keys
LookupO(1)O(1)Map.get versus obj[key]
DeleteO(1)O(1)delete obj[k] can deoptimise the object
SizeO(1)O(n)map.size is stored; Object.keys(o).length builds an array
IterateO(n)O(n)Map preserves insertion order; object keys reorder integer-like keys
Any key typeYesStrings and symbols onlyObject keys are coerced to strings, so 1 and '1' collide

Strings

Strings. They are immutable, which is the source of every surprise here.
OperationCostNote
s[i] / charCodeAtO(1)
s.lengthO(1)Counts UTF-16 units, not characters
+= in a loopO(n) amortisedEngines optimise this with ropes; still prefer an array and join
slice / substringO(k)Allocates. Inside a loop this is the hidden factor
split / joinO(n)
indexOf / includesO(n × m) worst caseNot the linear-time algorithm you might assume
localeCompareO(n)Far slower than <; only use it when you need collation
Concatenating in a nested loopO(n³)The classic accidental cubic. See lesson 03

Data structures side by side

The structures, and what each one is actually for.
StructureAccessSearchInsertDeleteSpace
Array (by index)O(1)O(n)O(n)O(n)O(n)
Dynamic array (at end)O(1)O(n)O(1)O(1)O(n)
Singly linked listO(n)O(n)O(1)O(1)O(n)
Stack / QueueO(n)O(n)O(1)O(1)O(n)
DequeO(1)O(n)O(1)O(1)O(n)
Hash map / set—O(1)O(1)O(1)O(n)
Binary heapO(1) peekO(n)O(log n)O(log n) popO(n)
Balanced BSTO(log n)O(log n)O(log n)O(log n)O(n)
Degenerate BSTO(n)O(n)O(n)O(n)O(n)
Trie—O(len)O(len)O(len)O(total chars)
Union-find—O(α(n))O(α(n))—O(n)

Sorting

Sorting. Know merge sort and quicksort well enough to write them; know the rest well enough to name them.
AlgorithmBestAverageWorstSpaceStable?
Merge sortO(n log n)O(n log n)O(n log n)O(n)Yes
QuicksortO(n log n)O(n log n)O(n²)O(log n)No
HeapsortO(n log n)O(n log n)O(n log n)O(1)No
Insertion sortO(n)O(n²)O(n²)O(1)Yes
Selection sortO(n²)O(n²)O(n²)O(1)No
Bubble sortO(n)O(n²)O(n²)O(1)Yes
Counting sortO(n + k)O(n + k)O(n + k)O(k)Yes
Radix sortO(d(n + k))O(d(n + k))O(d(n + k))O(n + k)Yes
Array.prototype.sortO(n)O(n log n)O(n log n)O(n)Yes

Graph algorithms

Graph algorithms. V is vertices, E is edges.
AlgorithmTimeSpaceWhat it answers
BFSO(V + E)O(V)Shortest path when every edge costs the same
DFSO(V + E)O(V)Reachability, cycles, components, ordering
Topological sort (Kahn)O(V + E)O(V)A valid dependency order, or detects a cycle
Union-find over E edgesO(E α(V))O(V)Connectivity as edges arrive
Dijkstra (binary heap)O(E log V)O(V + E)Cheapest paths, non-negative weights only
Bellman–FordO(V × E)O(V)Cheapest paths with negative edges; detects negative cycles
Floyd–WarshallO(V³)O(V²)All pairs at once. Fine for V up to a few hundred
Kruskal / PrimO(E log V)O(V + E)Minimum spanning tree
Adjacency list—O(V + E)The default. Iterating a vertex's neighbours is O(degree)
Adjacency matrix—O(V²)O(1) edge lookup, wasteful unless the graph is dense

Patterns

The patterns, and what each one costs.
PatternTimeSpace
Two pointersO(n), or O(n log n) if you sort firstO(1)
Sliding windowO(n)O(k)
Prefix sumsO(n) build, O(1) per queryO(n)
Hash map countingO(n)O(n)
Binary search on an arrayO(log n)O(1)
Binary search on the answerO(n log(range))O(1)
Monotonic stackO(n) amortisedO(n)
Top-k with a capped heapO(n log k)O(k)
Tree DFSO(n)O(h)
Tree / graph BFSO(n) or O(V + E)O(width)
Backtracking, subsetsO(n × 2ⁿ)O(n) plus output
Backtracking, permutationsO(n × n!)O(n) plus output
1D dynamic programmingO(n × choices)O(n), often O(1)
2D dynamic programmingO(mn)O(mn), often O(min(m,n))
Bitmask DPO(2ⁿ × n)O(2ⁿ)

Space complexity, counted honestly

Space is the half candidates forget, and interviewers ask about it precisely because it separates people who have thought about the solution from people who have recalled it.

What to say out loud

A complete answer has four parts, and it takes about fifteen seconds.

  1. Time, with the reason. “O(n log n), dominated by the sort; the sweep afterwards is linear.”
  2. Space, with the reason. “O(n) for the hash map, or O(1) if I sort in place instead.”
  3. Whether it fits. “With n up to 10⁵ that is about two million operations, so it is comfortable.”
  4. The trade-off you chose. “I could drop to O(1) space by sorting, but that loses the original indices, which this problem needs.”

That last point is what separates a good answer from a complete one. Interviewers are listening for evidence that you know your solution sits on a spectrum, and that you picked a point on it deliberately.

Newsletter

New writing, when it lands.

Occasional notes on shipping software with AI agents. No schedule, no filler, unsubscribe in one click.