← Back to Blog

Amortized Analysis

Understanding the Real Cost of Operations Over Time

Amortized Analysis

In algorithm analysis, some operations look expensive in isolation — but when averaged over many operations, they turn out to be efficient. That's where amortized analysis comes in.

Instead of analyzing the worst-case cost of a single operation, amortized analysis asks:

What is the average cost per operation over a sequence of operations?

It guarantees performance without using probability.

Why Amortized Analysis Is Needed

Consider a dynamic array (like Python lists or C++ vectors).

Most insertions take O(1). But occasionally, when the array is full, we must:

  • Allocate new memory
  • Copy all elements
  • Insert the new element

That resizing step costs O(n). So is insertion O(n)?

No. Because resizing happens rarely. Amortized analysis shows insertion is still:

O(1) amortized

Worst Case vs Amortized vs Average Case

Type Meaning
Worst Case Maximum cost of one operation
Average Case Expected cost over random inputs
Amortized Guaranteed average per operation over a sequence
⚠ Amortized ≠ Average Case

Amortized analysis does not rely on randomness. It is a deterministic guarantee over any sequence of operations.

The Three Methods of Amortized Analysis

  • Aggregate Method
  • Accounting Method
  • Potential Method

Aggregate Method

We compute the total cost of n operations, then divide by n.

Example: Dynamic Array Doubling

Assume initial size = 1 and capacity doubles when full. Insert elements one by one.

Resizing Pattern

Insert # Cost
11
22 (resize)
31
44 (resize)
51
61
71
88 (resize)

Resizing costs form a geometric series:

1 + 2 + 4 + 8 + ⋯ + n < 2n

Plus n simple inserts. Total cost:

3n

Amortized cost per insertion:

3n / n = 3 = O(1)
Aggregate Method illustration

Accounting Method (Banker's Method)

We assign artificial costs. Some operations pay extra and store "credits" to pay for future expensive operations.

Dynamic Array Example

Charge 3 units per insertion:

  • 1 unit → actual insert
  • 2 units → saved as credit

When a resize happens, use the saved credits to pay for copying. This ensures no operation ever runs out of budget. So amortized cost:

O(1)
Accounting Method illustration

Potential Method (Physicist's Method)

Uses a potential function Φ(state) that measures stored "energy" in the data structure.

Amortized cost of the i-th operation:

ĉᵢ = cᵢ + Φ(Dᵢ) − Φ(Dᵢ₋₁)

Where cᵢ is the actual cost and Φ is the potential.

Dynamic Array Potential Function

Let:

Φ = 2 · (number of elements) − capacity

When the array grows, potential decreases and pays for the copying cost — mathematically proving amortized O(1).

Potential Method illustration

Stack with Multipop Operation

Operations:

  • PUSH → O(1)
  • POP → O(1)
  • MULTIPOP(k) → up to O(k)

Worst case: MULTIPOP(n) = O(n).

But across a sequence, each element can be popped only once. So total pops ≤ total pushes. If we do n operations:

Total cost ≤ 2n

Amortized cost per operation:

O(1)

Binary Counter Example

Incrementing a binary number:

0000 → 0001
0001 → 0010
0010 → 0011
0011 → 0100

Sometimes many bits flip. Worst-case increment: O(log n).

But over n increments, each bit flips at most n times divided by powers of 2. Total flips:

O(n)

So amortized cost per increment:

O(1)

Amortized Analysis of Splay Trees

Splay trees use rotations to self-organize. A single operation may cost O(n), but using the potential method:

Amortized cost = O(log n)

Amortized vs Worst-Case Guarantees

Data Structure Worst Case Amortized
Dynamic Array Insert O(n) O(1)
Binary Counter O(log n) O(1)
Splay Tree O(n) O(log n)

Amortized guarantees are deterministic over a sequence — no randomness required.

When to Use Amortized Analysis

Used in:

  • Dynamic arrays
  • Hash tables resizing
  • Garbage collection
  • Network buffering
  • Persistent data structures
  • Functional programming structures

Why Amortized Analysis Works

Key principle: expensive operations are rare. If costly events happen infrequently enough, their cost spreads over many cheap operations, bringing the per-operation average down to a constant or logarithmic bound.

Common Mistakes

  • Confusing amortized with average-case
  • Forgetting to count the full sequence cost
  • Not justifying the potential function
  • Ignoring adversarial sequences

Mathematical Summary

If the total cost of n operations is:

T(n) ≤ c · n

Then the amortized cost per operation is:

T(n) / n = O(1)

Even if some individual operations cost O(n).

Real-World Impact

Amortized analysis explains why:

  • Python lists scale well
  • C++ vectors are efficient
  • Databases resize indexes safely
  • Memory allocators remain fast
  • Web servers handle traffic spikes
Without amortized guarantees

Systems would degrade unpredictably — a single expensive operation could stall an entire pipeline. Amortized analysis proves this cannot happen on average.

Final Summary

Amortized analysis studies performance over sequences, not single operations.

Three main methods:

  • Aggregate Method — sum total cost, divide by n
  • Accounting Method — assign credits to cheap ops, spend on expensive ones
  • Potential Method — use a potential function to track stored "energy"

It proves that some operations with bad worst-case behavior are still efficient overall — bridging the gap between theory and practical system design.