3.1.2 · D2Complexity Analysis

Visual walkthrough — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

2,962 words13 min readBack to topic

Before line one, four words we will use constantly:

Everything below is one long answer to: "as n grows, which shapes pull ahead, and why?"


Step 1 — The board: n on the floor, steps up the wall

WHAT. We set up the one arena every class lives in. The horizontal axis (the floor) is n, the input size. The vertical axis (the wall) is , the number of steps. Every algorithm is a curve climbing this wall as we walk right along the floor.

WHY. To compare growth we need them on the same picture. "Faster-growing" then simply means "the curve that ends up higher for large n". No formula yet — just a stage.

PICTURE. Look at figure s01: a flat line hugging the floor (that will become ) and a steep line rocketing up the wall. The eye already ranks them — that ranking is complexity.

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

Step 2 — O(1): the flat floor (no dependence on n)

WHAT. The simplest curve: a horizontal line. Grabbing arr[i] or stack.push() touches a fixed number of things regardless of how big the list is.

WHY THIS SHAPE. There is no loop over the data. Write the step count: The symbol c is a constant — it does not contain n anywhere. A quantity with no n in it cannot change when n changes. So the curve is dead flat.

PICTURE. Figure s02 draws as a level chalk line. As we slide right along n, the height never moves — that flatness is the visual signature of constant time.

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)
Recall Why "constant" and not "1"?

The 1 in is a placeholder for "some fixed number", not literally one step. Whether it's 1 step or 1000 steps, if that number never grows with n, it's — the tight estimate erases the exact value.


Step 3 — O(log n): halving the pile (dividing, never subtracting)

WHAT. Start with n items. Each step throws away half of what's left. How many steps until one item remains? That count is the height of the log curve.

WHY A LOG. First, name the thing we are counting: let k be the number of halvings (i.e. the number of steps) we perform. Now follow the pile size step by step — this is the derivation, drawn:

The exponent on the 2 counts how many cuts we have made, so after k cuts the pile is . We stop when the pile is a single item:

WHY the tool and not division or subtraction? We ask "2 raised to what power gives n?" — that question is the definition of . We reach for a log precisely because the process multiplies the shrink factor (÷2, ÷2, ÷2…) rather than removing a fixed amount each time. If we instead subtracted a constant each step, we'd get — the log is the fingerprint of dividing by a constant factor.

PICTURE. Figure s03 shows the pile as a bar being sliced in half over and over; the step counter on the side climbs by 1 every time the bar halves — so a million-item pile needs only ~20 slices. That brutal shrinking is why Binary-Search is so cheap.

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

Step 4 — O(n): one glance per item (the straight ramp)

WHAT. Do a fixed chunk of work once for every element: find the max, sum a list, scan for a value.

WHY LINEAR. One pass, one visit each:

Because n appears to the first power, doubling the input doubles the work — a perfectly straight ramp. This is the honest, "read everything once" cost, and it's the baseline every efficient algorithm is measured against.

PICTURE. Figure s04 lines up n boxes and a single arrow sweeping across them left to right, ticking the step counter once per box. Straight line, constant slope.

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

Step 5 — O(n log n): a stack of linear passes (the recursion tree)

WHAT. Split the data into halves, sort each half, then merge them back in one linear sweep. This is Merge-Sort. Its cost is described by a recurrence — a formula defining in terms of smaller T.

WHY this shape — build it from the tree. The recurrence is:

Draw it as a tree (why a tree? because each split spawns two children, exactly like branching):

  • Depth of the tree = how many times we can halve n before hitting size 1 → that's levels (we already earned this number k in Step 3!).
  • Work on each level = at level 0 there is one piece of size n costing ; at level 1, two pieces of size costing ; at level 2, four pieces of size costing ; and so on. Every level costs exactly because the pieces always add back up to n.

Now why multiply — because total cost is the sum over levels, and every term in that sum is the same :

Adding the same value times is multiplication — that is exactly why "work-per-level × number-of-levels" is legitimate here.

PICTURE. Figure s05 draws the recursion tree: each row labelled with its total work on the right, the number of rows braced as on the left. The sum "rows × work-per-row" is the whole cost — see it as the area of the tree. (The formal machinery behind this is Recurrence-Relations and the Master-Theorem.)

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

Step 6 — O(n²): everyone meets everyone (the filled square)

WHAT. For each element, do work proportional to all elements — a loop inside a loop.

WHY QUADRATIC. Count the pairs. The n×n grid of "element i talks to element j" has:

Even the triangular version (inner loop starts at i) gives:

The tight estimate keeps the biggest term and drops the constant and the lone , leaving — the half-square grows in the same shape as the full square.

PICTURE. Figure s06 shades the full n×n grid (all pairs) and, over it, the triangular half. Same parabolic growth — the eye sees the shaded area balloon as n widens.

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

Step 7 — O(n³): a loop inside a loop inside a loop (the solid cube)

WHAT. Three nested loops, each running n times — the classic being naive multiplication of two n×n matrices: for each output cell (i, j) you sum over a running index k.

WHY CUBIC. Count how the loops multiply, one nesting at a time:

Each loop is inside the previous, so their counts multiply (Step 6's rule, applied twice). Where Step 6 filled a flat n×n square of work, here you fill a solid n×n×n cube: one unit of work for every triple .

PICTURE. Figure s07 stacks the flat square of Step 6 into a solid cube of side n; the number of little unit cells inside is , and the code skeleton on the side shows the three nested loops feeding it. As n grows the cube's volume — the work — swells far faster than the square's area.

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

Step 8 — O(2ⁿ): the doubling tree (a binary choice per item)

WHAT. For each of the n items, make one binary choice — take it or skip it. Count all the ways.

WHY EXPONENTIAL. Each new item doubles the number of possibilities, because it plugs into every existing combination twice (once "taken", once "skipped"):

As a recurrence, "solve for n items = twice solve for n−1 items":

Note the crucial difference from Step 3: here n sits in the exponent (it pushes 2 upward), whereas in the n was inside the log. Exponent-in-the-power = explosion; that's why naive recursive Fibonacci and brute-force subset search are hopeless past ~40 items (deep dive: Dynamic-Programming tames these).

PICTURE. Figure s08 grows a binary tree: 1 node → 2 → 4 → 8, doubling each level, with the leaf count braced at the bottom. Then it overlays against on the arena and marks the crossing near n≈4 where exponential overtakes quadratic forever.

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

Step 9 — O(n!): every ordering (the fastest explosion)

WHAT. Enumerate every possible order (permutation) of n items — brute-force Travelling Salesman, generating all arrangements.

WHY FACTORIAL, and why it beats 2ⁿ. Building an ordering: n choices for the first slot, then n−1 for the second, and so on:

Now stack it against factor by factor — both are products of n numbers:

From the third factor onward () every factor of is larger than the matching 2. So pulls ahead — first at n=4 () — and the gap widens without bound. Factorial is its own, worse class; this is why exact TSP is intractable for large n.

PICTURE. Figure s09 places against term-by-term as two rows of factors, highlighting where 's factors overtake the constant 2s, then plots both curves so visibly tears away above .

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)

The one-picture summary

WHAT. Every class from Step 2 to Step 9, on one arena, with the two crossings marked and the ladder read off by who ends up on top.

PICTURE. Figure s10 layers all eight curves — flat , the crawling , the straight ramp , the slightly-bent , the parabola , the steeper cube , the wall-climbing , and the near-vertical . The vertical stacking on the right edge is the ladder .

Figure — Common complexities — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!)
Recall Feynman: the whole walkthrough in plain words

Picture a big arena. The floor counts how many sheets of homework you're given; the wall counts how much work you do.

  • Grab the top sheet only → flat line (). Bigger pile, same effort.
  • Play higher/lower on a sorted pile, tearing it in half each guess → a line that barely rises (): a million sheets, ~20 guesses.
  • Read every sheet once → a straight ramp ().
  • Split the pile in halves, sort each, merge — levels of -work each, added up → a slightly steeper ramp ().
  • Compare every sheet to every other → a parabola (), the filled square of all pairs.
  • Do that comparison nested three deep → a solid cube of work ().
  • For each sheet decide keep-or-toss and try every combination → a doubling tree that shoots up the wall (); it passes the parabola around 4 sheets.
  • Try every possible order to stack them → a curve that goes almost straight up (), leaving even far below from 4 sheets on. The faster your curve climbs the wall as sheets pile on the floor, the worse — and now you've seen exactly why the ladder is ordered the way it is.

Related: the parent topic · 3.1.03-Best-Worst-Average-Case · 3.1.01-Big-O-Notation