skip to content

A map-tile pyramid halves image width per level — why is the level count O(log n), not O(n)?

level: middleimportance: should knowfreq 58%

answer

  1. count levels, not pixels
  2. each level halves the width
  3. how many halvings reach one?
  4. that count is the base-two logarithm
  5. changing the divisor is a constant factor

basics

~20 s

Each level divides the width rather than subtracting from it, so the width reaches one after about log2(n) halvings, where n is the starting width. Repeated division gives a logarithmic count; repeated subtraction is what would give a linear one.

solid answer

~40 s

The loop variable here is *divided* each pass, not decremented. Starting at width n, successive levels are `n/2, n/4, n/8, ...`, and the loop stops when the width reaches 1 — which happens after the number of halvings k satisfying `n / 2^k = 1`, so `k = log2(n)`. A 4096-pixel-wide source needs 12 levels, not 4096 and not 2048. The base of the logarithm is irrelevant to the class: quartering the width each level gives `log4(n) = log2(n)/2`, a constant factor smaller and still O(log n). The general rule is divide versus decrement — dividing the remaining range by any constant factor greater than one gives a logarithmic trip count, while subtracting a constant, even a large one, stays linear.

go deeper

for a junior

Recall that repeatedly halving a value reaches one after about log2 of it steps, and be able to give a number: a width of 4096 takes 12 halvings, not thousands.

for a middle

Explain the divide-versus-decrement distinction and solve n / 2^k = 1 out loud. Show that changing the divisor only changes the logarithm's base, which is a constant factor.

for a senior

Multiply trip count by work per trip before quoting a total. Recognise when per-level work shrinks geometrically, making the total linear, versus when each pass repeats full-size work and the logarithm really does multiply.

for a principal

Judge whether the extra levels are worth their storage and rebuild cost for the access patterns you actually serve, and set how deep the pyramid goes rather than defaulting to all the way down.

## The loop shape A zoom pyramid stores a map image at successively coarser resolutions: the base level at full detail, then a level at half the width, then a quarter, and so on until the whole world fits in a single small tile. The build loop looks like: ``` width = n levels = 0 while width > 1 build_level(width) width = width / 2 levels = levels + 1 ``` The question is how many times that loop body runs. ## Divide versus decrement This is the whole distinction, and it is the one candidates most often blur. - **Decrement:** `width = width - 1` (or `- 100`) reaches 1 after about n steps (or n/100). Subtracting a constant leaves the trip count **linear**: O(n). Dividing the constant out changes the coefficient, never the class. - **Divide:** `width = width / 2` reaches 1 after k steps where `n / 2^k = 1`, that is `2^k = n`, that is `k = log2(n)`. Repeated division gives a **logarithmic** trip count. The intuition worth carrying is that the logarithm is the inverse of exponential growth: asking "how many halvings take n down to 1" is the same as asking "how many doublings take 1 up to n". Doubling reaches large numbers fast, so the answer is small. For n = 4096 it is 12. For n = 1,000,000 it is about 20. For the number of atoms in a rock it is a couple of hundred. Logarithmic loops essentially never run many times, which is why an O(log n) step is treated as nearly free. ## Why the base does not matter Suppose the pyramid quartered the width per level instead of halving it. Then the level count is `log4(n)`. By the change-of-base identity, `log4(n) = log2(n) / log2(4) = log2(n) / 2` — exactly half as many levels. Half is a constant factor, and big-O drops constant factors, so both are O(log n). This is why the notation is normally written without a base at all. It is a real difference in practice (twelve levels versus six) and no difference in class. The misconception to name explicitly: `O(log4 n)` is not a smaller complexity class than `O(log2 n)`. Any two logarithms differ by a constant multiplier. Contrast this with `O(n)` versus `O(n^2)`, where no constant can bridge the gap. ## The follow-on trap: level count is not total work A logarithmic *number of levels* does not by itself make the build logarithmic, because each level does a different amount of work. If the base image is n by n pixels, each level has a quarter of the pixels of the level below it: `n^2, n^2/4, n^2/16, ...`. The total is a geometric series with ratio 1/4, which sums to `n^2 * 4/3`. So building the whole pyramid costs about one and a third times the base image — **linear in the number of source pixels**, not `pixels * log`. This is the general lesson about halving loops. When the per-iteration work is constant, `log n` iterations means O(log n) total. When the per-iteration work *shrinks geometrically*, the sum is dominated by the first term and the total is proportional to that first term. When the per-iteration work is *constant and large* — say each level re-reads the full source image — then `log n` iterations really do multiply, and the total becomes `n^2 log n`. Always multiply the trip count by the work per trip; do not read the loop's trip count as if it were the answer. ## Recognising the pattern elsewhere The same counting argument covers any loop whose control variable is multiplied or divided by a constant factor each pass: stepping through the levels of a balanced tree, walking the doubling capacities of a growing buffer, or ranging over powers of two. In each case the number of steps is logarithmic in the ratio between the start and stop values, and the base only shifts the constant. Conversely, a loop that adds or subtracts a fixed amount — no matter how large — is linear, and a loop that decrements by one from a bound that itself depends on an outer index gives the triangular sum instead.

  • Does the logarithmic level count make the whole pyramid build O(n log n)?
    No. Each level holds a quarter of the pixels of the level below, so the work per level shrinks geometrically: the series n^2 + n^2/4 + n^2/16 + ... sums to about 4/3 of the base level. The build is linear in the number of source pixels. Trip count alone is never the answer — multiply it by the work per trip.
  • A loop subtracts 100 from its bound each pass instead of dividing by 2. Same class?
    No, that is O(n). Subtracting a fixed amount takes about n/100 passes, and dividing out the 100 leaves a linear trip count. Only repeated division by a factor greater than one produces a logarithm. Decrement gives linear, divide gives logarithmic — the size of the constant never bridges those classes.
  • Is a loop that quarters its range each pass in a better complexity class than one that halves it?
    No. Quartering gives log4(n) passes, which equals log2(n)/2 by change of base — half as many iterations, so a constant factor better and the same O(log n) class. That is why the base is normally omitted from the notation. It is a genuine practical difference and not a class difference.

Counting levels is like folding a long strip of paper in half repeatedly: a strip a thousand units long is down to one after about ten folds, not a thousand.

saying these in an interview costs you the question

  • Says halving the width makes the loop O(n/2), so linear
  • Claims O(log4 n) is a smaller class than O(log2 n)
  • Treats subtracting a large constant as if it were dividing
  • Reads the level count as the total build cost
  • Cannot say roughly how many halvings a million takes

context