Amortized Analysis

RoadmapsDSA

Overview

Amortized analysis determines the average cost per operation over a worst-case sequence of operations, NOT the average case for a single random operation. It proves that even if a few individual operations are expensive (like resizing an array), the cost spread across all operations stays low. The three standard techniques are the aggregate method, the accounting method, and the potential method.

Worst-case per-operation analysis can be misleadingly pessimistic. If you judge a dynamic array's append by its worst case alone, you would conclude it is O(n) and avoid using it — even though a sequence of n appends costs only O(n) total, making each append O(1) amortized. Amortized analysis gives the true average cost per operation without relying on probabilistic assumptions.

Where used: Dynamic arrays (Python list, Java ArrayList, C++ vector): append is O(1) amortized because resizes are exponentially rare, Hash table rehashing: doubling the table and rehashing all keys is O(n), but it happens only every O(n) insertions, Splay trees and union-find with path compression: individual operations can be slow but any sequence of m operations completes in O(m log n) or O(m alpha(n)) total

Why learn this

Aha moment

# Dynamic array: append 8 elements, starting capacity 1
# Capacity: 1 -> 2 -> 4 -> 8  (3 resizes)
# Resize copies:  1 + 2 + 4 = 7 elements copied
# Non-resize appends: 8 - 3 = 5 (cost 1 each = 5)
# Total cost: 7 + 8 = 15 operations for 8 appends
# Amortized cost per append: 15/8 < 2
#
# For n appends: total resize copies = 1+2+4+...+n = 2n-1
# Total cost: (2n - 1) + n = 3n - 1 -> O(n) total -> O(1) each

Prediction: With 3 resizes that copy 1, 2, and 4 elements, the total cost must be high.

Common guess: The resizes make append more like O(n) overall.

Even though resizes copy 1+2+4 = 7 elements, there are 8 total appends, so the average cost is less than 2 operations per append. The crucial insight is that each element is copied at most O(log n) times across all resizes, and the geometric series ensures the total copy work is bounded by 2n. Expensive operations happen so rarely that they are absorbed by the many cheap ones.

Common mistakes

Glossary

probabilistic assumptions
Relying on random chances instead of mathematical guarantees.
geometric series
A sequence of numbers where each term is found by multiplying the previous one by a fixed number.

Recall questions

Understanding checks

A colleague proposes that instead of doubling, a dynamic array should add 100 extra slots each time it runs out of space, because 'we waste less memory.' Why does this destroy the amortized O(1) append guarantee?

With fixed-increment growth, after inserting n elements you trigger about n/100 resizes, and the i-th resize copies roughly 100*i elements. The total copy cost is proportional to 100 * (1 + 2 + ... + n/100) = O(n^2/100) = O(n^2). Dividing by n gives O(n) amortized cost per append, not O(1).

The geometric doubling strategy is not arbitrary — it ensures the total resize cost forms a geometric series that converges to O(n). Linear growth produces an arithmetic series that diverges to O(n^2). The growth factor must be multiplicative, not additive.

A developer avoids using Python lists for a real-time audio processing buffer because 'append is O(n) when it resizes, and audio stutters are unacceptable.' Is this reasoning valid or flawed?

The reasoning is VALID. In real-time systems, worst-case latency for every individual operation matters, not amortized averages. A single O(n) resize during audio playback causes a perceptible stutter. A pre-allocated ring buffer with true O(1) worst-case is the correct choice.

This shows the boundary of amortized analysis: it guarantees low AVERAGE cost but not low WORST-CASE cost for each individual operation. For latency-sensitive systems, amortized guarantees are not strong enough.

Practice tasks

Trace the resize sequence for 16 appends

A dynamic array starts at capacity 1 and doubles when full. Trace 16 appends: for each append, record the current capacity, whether a resize happens, and the number of elements copied during that resize. Sum the total copies and compute the amortized cost per append.

Continue learning

Previous: Big-O Notation

Previous: Common Complexities

Previous: Logarithms & Powers of Two

Return to DSA Roadmap