Skip to content

Amortized Analysis

Amortized analysis computes the average cost per operation over a sequence of operations, providing a guaranteed bound regardless of input. Unlike average-case analysis (which depends on input distribution), amortized cost applies to all possible operation sequences.

Key Facts

  • Amortized cost = total cost of n operations / n
  • NOT dependent on input probability - guaranteed bound over all sequences
  • Individual operations may be expensive, but the average is cheap
  • Most common example: dynamic array (Python list) append

Patterns

Dynamic Array (Python list) Insertion

When the array is full, double capacity and copy all elements. Resize happens at sizes 1, 2, 4, 8, 16, 32, ...

Cost of n insertions without resize: n
Cost of resize operations: 1 + 2 + 4 + 8 + ... + n = 2n - 1

Total cost of n insertions = n + (2n - 1) ~ 3n
Amortized cost per insertion = 3n / n = O(1)

Even though a single resize costs O(n), it happens so rarely that the amortized cost per append() is O(1).

Key Distinction

Concept Depends on Guarantee
Worst case Single worst input Per-operation
Average case Input probability distribution Expected over random inputs
Amortized Sequence of operations Average per operation, any sequence

Gotchas

  • Amortized O(1) does NOT mean every operation is O(1) - individual operations can be O(n)
  • Not useful for real-time systems where every single operation must be fast
  • The guarantee is over the entire sequence, not per-operation
  • Python list.append() is amortized O(1) but a single append can trigger O(n) copy

See Also

  • [[complexity-analysis]] - fundamental complexity concepts
  • [[python:lists-and-tuples]] - Python list internals