Time Complexity
Time complexity models how an algorithm's operation count grows with a declared input measure. It predicts scaling under an abstract cost model; it does not replace measurement of an implementation on representative hardware and data.
State the model
Before simplifying a bound, identify:
- what means, or whether several parameters such as and matter;
- which operations are treated as constant time;
- worst, average, expected, amortized, or output-sensitive behavior;
- assumptions about representation, ordering, randomness, and numeric bit size.
For example, BFS is with adjacency lists, not merely , while an algorithm polynomial in a numeric capacity may be pseudo-polynomial in encoded input length.
Asymptotic notation
- : an eventual upper bound.
- : an eventual lower bound.
- : matching upper and lower bounds.
Big-O is not a synonym for “worst case.” Case analysis and asymptotic notation are separate: one may state an expected runtime or a worst-case bound.
Analysis patterns
- Consecutive phases add; the dominant growing term often controls the result.
- Nested work multiplies only when the inner cost applies for each outer step.
- Halving or doubling an interval usually produces logarithmic depth.
- Recursive algorithms require a recurrence or an accounting argument.
- Enumeration must include output size: producing permutations cannot take sub-factorial total output time.
Common growth classes
This ordering is asymptotic. Constants, cache behavior, vectorization, allocation, and input distribution still determine practical crossover points.
Quantifiers and worked counts
For eventually nonnegative functions, means that constants and exist such that for every . They must not grow with . For and , , proving , not just an upper bound.
def pair_count(n):
count = 0
for i in range(n):
for j in range(i):
count += 1
return count
assert pair_count(4) == 6
assert pair_count(0) == 0
For nonnegative integer n, the inner body runs
times. If instead an inner variable doubles from 1 while below n, there
are iterations for . Repeating that entire
inner loop for each of outer steps costs , not
merely because two loops are nested.
Best, worst, average, expected, amortized
Best and worst take the minimum and maximum over inputs of a fixed size. Average case takes an expectation over a declared input distribution. Randomized expected cost averages over the algorithm's random choices, possibly for any fixed input. These are different sources of randomness.
Amortized cost needs no probability model: it bounds the total cost of an operation sequence. Consider an initially empty dynamic array whose capacity starts at one and doubles when full. Across appends, copying at resizes costs , and the new writes cost . Total work is , so an append costs amortized even though one resize costs . For eight appends, copied slots total and new writes total eight. Growing capacity by only one instead copies slots and loses the constant amortized bound. This argument counts reference-slot operations, not arbitrary-size integer arithmetic, expensive comparisons, or wall-clock latency.