Intuition The ONE core idea
Complexity analysis is about how the amount of work grows when the input grows — nothing more. If you can read a formula like 2 k or log 2 n as a picture of things multiplying, halving, or piling up , then every complexity class becomes a story you can see rather than a symbol you have to memorise.
This page assumes nothing . Every letter, every squiggle the parent note uses — we build it here from the ground up, in the order that each one needs the one before it. When you finish, re-read the parent note (the parent topic ) and every symbol will already be familiar.
n means
n is a plain-words placeholder for "how big is the thing we are working on?" If you have a list of 500 names, then n = 500. If you have a pile of 10 homework sheets, n = 10.
Picture: a row of boxes. Count the boxes — that count is n.
Domain: n is a non-negative whole number (n = 0 , 1 , 2 , 3 , … ). You cannot have half a box or a negative pile. The edge case n = 0 means "empty input" — no items at all, which is always a valid thing to ask about.
Why does the topic need n? Because complexity is never a single number. "This algorithm takes 40 steps" is useless — 40 steps for how much input? We always ask: as n gets bigger, what happens to the work? So n is the knob we turn, and everything else describes what happens when we turn it.
T(n) means
T(n) reads out loud as "T of n ". It is a machine: you feed it an input size n, and it hands you back the number of basic steps the algorithm takes for that size. T stands for time (in steps, not seconds).
Picture: a vending machine with a slot labelled n and an output tray labelled "step count".
T(n) instead of just a number
Because the answer depends on n. If checking one box takes 1 step and you have n boxes, then T ( n ) = n . Turn the knob to n = 500 and you read T ( 500 ) = 500 . The parentheses (n) are how maths says "this value depends on n". Since n is a non-negative whole number, T(n) too is a step count — a non-negative whole number.
The whole subject is really the study of the shape of T(n) — does it stay flat, climb gently, or shoot up like a rocket?
n² means
n² (read "n squared ") means n multiplied by itself: n × n . n³ ("n cubed ") means n × n × n . The small raised number — the exponent — just counts how many copies of n are multiplied together .
Picture: n² is the number of dots in a square grid that is n dots wide and n dots tall. n³ is a solid cube , n on each side.
Why the topic needs this: a nested loop — a loop inside a loop — touches every pair of items. If the outer loop runs n times and, for each of those, the inner loop also runs n times, the total is n × n = n 2 . The square grid in the figure is that pair-counting. Three nested loops fill a cube: n 3 .
n² is not 2n
Why it feels the same: both have a 2 and an n. The truth: 2n means n + n (two piles side by side), while n² means n × n (a whole grid). At n = 100, 2n = 200 but n² = 10\,000. The exponent multiplies; the front number adds.
2ᵏ means
Now the 2 is on the bottom and the letter is the exponent : 2 k means "multiply k twos together" — 2 × 2 × ⋯ × 2 (k times). Each extra k doubles the result.
Picture: a tree that splits in two at every level. Level 0 has 1 node, level 1 has 2, level 2 has 4, level 3 has 8… level k has 2 k .
Domain: k is a non-negative whole number (k = 0 , 1 , 2 , … ) — it counts how many doublings have happened, and you cannot do half a doubling. The edge case k = 0 means "no doublings yet": 2 0 = 1 , the single root of the tree.
Why does the topic care? Two reasons, and they are mirror images:
Doubling upward (2 n ): if every new item forces a keep-or-toss choice, the number of combinations doubles with each item. n items → 2 n combinations. This is where the "exponential" wall comes from.
Halving downward (leads to log, next section): if each step throws away half the data, you are running the doubling tree in reverse.
Worked example Feel the doubling
Fold a paper in half repeatedly. After k folds it is 2 k layers thick. Just 20 folds = 2 20 ≈ a million layers. Small k, huge result — that is exponential growth in your hands.
Powers of 2 answer: "I doubled k times — how big did I get?" The logarithm answers the exact reverse question.
log₂ n means
log₂ n (read "log base 2 of n ") asks: "To what power must I raise 2 to reach n?" In symbols, if 2 k = n , then k = log 2 n . So log 2 8 = 3 , because 2 3 = 8 .
Domain: unlike n (which may be 0), the logarithm is only defined for n ≥ 1 here — you cannot ask "how many doublings reach 0", because no power of 2 ever equals 0, and log 2 0 has no value (it runs off to negative infinity). So whenever we write log 2 n in this topic we quietly assume n ≥ 1 (a non-empty input). At the boundary, log 2 1 = 0 : a single item needs zero halvings — it is already down to one.
Picture: the halving tree from the previous section, but you count the number of levels it takes to shrink n items down to 1.
Intuition Why "how many halvings" and why it is small
Start with n items. Cut in half → n/2 left. Cut again → n/4. After k cuts you have n / 2 k items. You stop when 1 item remains:
2 k n = 1 ⇒ 2 k = n ⇒ k = log 2 n .
The magic: log grows painfully slowly . A million items (n = 1 0 6 ) needs only about 20 halvings, because 2 20 ≈ 1 0 6 . That is why "divide in half each step" (like Binary-Search ) is so fast.
Definition The ceiling symbol
⌈ x ⌉
⌈ x ⌉ (read "ceiling of x ") means "round x up to the nearest whole number that is at least as big as x" . So ⌈ 3.32 ⌉ = 4 , ⌈ 5 ⌉ = 5 (already whole), ⌈ 0.1 ⌉ = 1 .
Picture: a number line — you slide x upward to the first whole-number tick mark at or above it.
Why we need it: step counts must be whole steps, so whenever a formula gives a fraction we round it up to the next full step.
Common mistake But real halvings must be whole steps
The subtlety: log 2 n is only a clean whole number when n is an exact power of 2 (like 8 , 16 , 32 ). For an in-between size like n = 10, log 2 10 ≈ 3.32 — but you cannot do 0.32 of a halving . In practice you round up using the ceiling: you need ⌈ log 2 n ⌉ halvings, because the last partial cut still costs a full step. For n = 10 that is ⌈ 3.32 ⌉ = 4 halvings (10 → 5 → 3 → 2 → 1 ). Big-O ignores this rounding — it changes the count by less than 1 — so we still call it O ( log n ) .
Common mistake Why the base of the log doesn't matter for Big-O
Why it feels wrong: log 2 n and log 10 n give different numbers. The truth: they differ only by a fixed multiplier: log 10 n = log 2 n ÷ log 2 10 . Since Big-O (next section) throws away constant multipliers, we just write log n with no base.
∑ symbol means
∑ is a capital Greek letter sigma , and it means "add these up" . The expression
∑ i = 1 n i
reads: "let i walk from 1 up to n, and add together every value of i along the way" — that is 1 + 2 + 3 + ⋯ + n .
Picture: a staircase of blocks — a column of height 1, then 2, then 3, …, up to n. The total number of blocks is the sum.
Domain: the index i is a whole number that steps one-at-a-time from the bottom value to the top value (i = 1 , 2 , … , n here). If the top is below the bottom (an empty range , e.g. summing from 1 to 0), the sum is defined to be 0 — you added nothing.
Intuition Why the topic needs sums
When you count the work of a loop, you are really adding: "the inner loop did 5 steps, then 4, then 3…". A sum packages all of that. The staircase picture reveals the closed form:
∑ i = 1 n i = 2 n ( n + 1 ) .
Two copies of the staircase interlock into a full rectangle of n × ( n + 1 ) blocks, so one staircase is half of that. For large n this behaves like n 2 /2 — a quadratic. That is why a triangular nested loop is still O ( n 2 ) .
Now the crown symbol of the whole topic.
O(f(n)) means — plainly, then formally
Plainly: O(...) (read "Big-O of… ") is a label for how fast T(n) grows as n gets large — ignoring constant multipliers and smaller side-terms. Saying an algorithm is O ( n 2 ) means: for big n, its work grows like n², give or take a constant factor.
Formally: we write T ( n ) = O ( f ( n )) when there exist two fixed positive numbers — a constant c and a threshold n 0 — such that
T ( n ) ≤ c ⋅ f ( n ) for every n ≥ n 0 .
In words: past some starting point n 0 , the curve T(n) never rises above a scaled copy c ⋅ f ( n ) of the reference curve. The c absorbs the constant factor we chose to ignore; the n 0 says "we only promise this for large enough n".
Picture: a family of curves on a graph. Big-O says "past n 0 , your T(n) curve stays under c ⋅ f ( n ) ."
Definition The simplest class:
O(1) — constant time
O ( 1 ) is Big-O with the reference curve f ( n ) = 1 — a flat line . It means the work does not depend on n at all : a fixed, bounded number of steps whether the input is tiny or gigantic. Reaching straight into a shelf for the 3rd book (arr[2]) costs the same whether the shelf holds 5 books or 5 million.
Picture: a perfectly horizontal line — as n slides right, the height never changes.
Why the 1? There is no n in a constant, so we write the plainest non-zero reference: 1. Formally, T ( n ) ≤ c ⋅ 1 = c for all n — the work stays under some fixed ceiling c forever.
Intuition Why we drop constants and smaller terms
Suppose T ( n ) = 3 n 2 + 100 n + 7 . For n = 1000, the 3 n 2 term is 3 000 000 ; the 100 n term is 100 000 ; the 7 is nothing. The biggest term dominates and everything else fades into the noise. Big-O keeps only that dominant shape → O ( n 2 ) . Formally you would pick, say, c = 4 and some n 0 so that 3 n 2 + 100 n + 7 ≤ 4 n 2 for all n ≥ n 0 — the extra n 2 of headroom swallows the smaller terms. This is the point of "asymptotics": large-n behaviour is all that matters. (Formal rules live in 3.1.01-Big-O-Notation .)
Common mistake Big-O is about
large n, not small n
Why it trips people: it feels like a lower Big-O always wins. The truth: Big-O hides the constant c, and for small inputs (below n 0 ) the constant can dominate. An O ( n 2 ) routine with a tiny constant can beat an O ( n log n ) one with a huge constant when n is small. Big-O is a promise about the far right of the graph — for n beyond n 0 .
≪ means here — and how it differs from numeric <
Ordinary < compares two numbers : 3 < 5 is a fact about those two values. Between complexity classes , though, < (and its emphatic cousin ≪, "much less than ") compares growth rates , not single values. Writing n ≪ 2 n means "for large enough n, 2ⁿ leaves n hopelessly behind, and the gap only widens."
How to read/formalise it: f ( n ) ≪ g ( n ) (equivalently "f grows strictly slower than g ") is just Big-O with a one-way twist — f ( n ) = O ( g ( n )) but g ( n ) = O ( f ( n )) . So the class-level < is really a statement about Big-O, whereas the numeric < is about two plain numbers. When you see < between formulas like n 2 < 2 n in a growth ladder, read it as "the left class is eventually dwarfed by the right", not "true at every single n" (indeed n 2 > 2 n for n = 3).
Picture: two curves; past some crossing point the faster one rockets up and never comes back down to the slower one.
That is exactly the meaning inside the parent note's ladder
1 ≪ log n ≪ n ≪ n log n ≪ n 2 ≪ n 3 ≪ 2 n ≪ n !
— each class is eventually dwarfed by the next.
n! means
n! (read "n factorial ") means multiply every whole number from 1 up to n: n ! = 1 × 2 × 3 × ⋯ × n . So 4 ! = 1 ⋅ 2 ⋅ 3 ⋅ 4 = 24 .
Picture: arranging n different books on a shelf. The first slot has n choices, the next has n-1 left, then n-2… multiply them all: that is the number of possible orderings .
Domain and edge case: n here is a non-negative whole number . The corner case is 0 ! = 1 — there is exactly one way to arrange an empty shelf (the "do nothing" arrangement), so the empty product is defined as 1, not 0. From there 1 ! = 1 , 2 ! = 2 , 3 ! = 6 , and the product runs upward.
n! is the worst common class
Compare it factor-by-factor with 2 n :
n ! = 1 ⋅ 2 ⋅ 3 ⋅ 4 ⋯ n , 2 n = 2 ⋅ 2 ⋅ 2 ⋅ 2 ⋯ 2.
Both are products of n factors, but in n! almost every factor (3, 4, 5, …) is bigger than 2 . So n! pulls ahead and stays ahead from n = 4 onward (24 > 16 ). Anything that tries every ordering — brute-force route-planning — lives here.
T of n = steps as function of n
exponents n squared n cubed
logarithm = how many halvings
summation adds up loop work
factorial = every ordering
Growth ladder and much-less-than
Common Complexities topic
Read it top to bottom: n seeds everything; exponents, doubling, and halving give the shapes ; summation and Big-O let us label a piece of code with a shape; the ladder orders the shapes — and that is the topic.
Cover the right side and answer out loud. If any one stumps you, re-read its section above before opening the parent note.
What does the letter n stand for, and what values may it take? The size of the input — a non-negative whole number (0 , 1 , 2 , … ); n = 0 means empty input.
Read T(n) in plain words. "T of n" — the number of basic steps the algorithm takes for an input of size n.
What does the exponent in n² count? How many copies of n are multiplied together — here two, so n × n .
What does 2^k mean, what values may k take, and what real process does it picture? Multiply k twos together (k a non-negative whole number, 2 0 = 1 ); it pictures repeated doubling.
log₂ n answers which question, and for which values of n is it defined?"To what power must I raise 2 to get n?"; defined only for n ≥ 1 (no power of 2 equals 0), with log 2 1 = 0 .
What does ⌈ x ⌉ mean, and why do step counts use it? "Ceiling of x" — round x up to the nearest whole number at or above it; step counts must be whole steps, so a fractional formula rounds up.
How many halvings does a non-power-of-two n need? ⌈ log 2 n ⌉ — round the log up, since the last partial cut still costs a full step.
What does the summation index i range over, and what is an empty sum? i steps through whole numbers from bottom to top; if the range is empty the sum is 0.
What is ∑ i = 1 n i in closed form? 2 n ( n + 1 ) , which grows like n 2 .
What does the class O(1) mean and what does its curve look like? Constant time — work independent of n, a fixed bounded number of steps; its curve is a flat horizontal line.
State the formal definition of T ( n ) = O ( f ( n )) . There exist constants c > 0 and n 0 with T ( n ) ≤ c ⋅ f ( n ) for all n ≥ n 0 .
When we write n ≪ 2 n , are we comparing numbers or growth rates, and how does that differ from numeric <? Growth rates: n = O ( 2 n ) but not vice versa; numeric < compares two plain values, class < compares eventual growth.
What does n! count, what is 0 ! , and why does it beat 2ⁿ? Orderings of n items; 0 ! = 1 (one way to arrange nothing); most of its factors exceed 2, so it overtakes 2 n from n = 4.