3.3.7Hashing

Amortized O(1) operations

1,998 words9 min readdifficulty · medium

WHAT is amortization?

The three standard methods:

  1. Aggregate method — total cost / n.
  2. Accounting method — charge each cheap op a little extra ("credit") to pre-pay future expensive ops.
  3. Potential method — define a potential function Φ\Phi that stores "saved up" work.

WHY does a hash table / dynamic array need this?


HOW: deriving the doubling cost from scratch

Suppose we start empty and push nn items. We double capacity each time the array is full. Capacities reached: 1,2,4,8,1, 2, 4, 8, \dots

Step 1 — cheap inserts. Each of the nn pushes costs 11 to write the element. cheap cost=n\text{cheap cost} = n Why this step? Every element must be written exactly once into its slot.

Step 2 — copy costs at resizes. A resize at capacity 2k2^k copies 2k2^k old elements. Resizes happen at sizes 1,2,4,,2m1, 2, 4, \dots, 2^m where 2mn2^m \le n. copy cost=1+2+4++2m=i=0m2i=2m+11\text{copy cost} = 1 + 2 + 4 + \dots + 2^m = \sum_{i=0}^{m} 2^i = 2^{m+1} - 1 Why this step? Geometric series — each doubling copies the whole current array once.

Step 3 — bound the sum. Since 2mn2^m \le n, we have 2m+11<2n2^{m+1}-1 < 2n. copy cost<2n\text{copy cost} < 2n

Step 4 — total and divide. Total=n+2n=3n=O(n)\text{Total} = n + 2n = 3n = O(n) Amortized cost per push=3nn=3=O(1)\boxed{\text{Amortized cost per push} = \frac{3n}{n} = 3 = O(1)}

Why this works: the copies form a geometric series that sums to a constant multiple of nn, not n2n^2. The rare doublings are "paid for" by the many cheap inserts before them.

Figure — Amortized O(1) operations

The Accounting Method (intuition for the "3")


The Potential Method (formal)


Worked Examples


Common Mistakes


Flashcards

What does "amortized O(1)" mean precisely?
Total cost of n operations is O(n), so cost per operation averaged over the sequence is O(1) — a worst-case guarantee over a sequence, not per single op.
Why is doubling array capacity amortized O(1) per insert?
Copy costs form a geometric series 1+2+4+…+2^m < 2n, plus n writes → total 3n = O(n), so 3 per op.
What is the total copy cost when growing by +1 each time, and the amortized cost?
Copy cost = n(n-1)/2 = O(n²); amortized = O(n), NOT constant.
Difference between amortized and average-case complexity?
Amortized = deterministic worst-case over a sequence; average-case = expectation over a probability distribution of inputs.
State the potential function used for dynamic array doubling.
Φ = 2·size − capacity (≥0 when ≥ half full).
In the accounting method, how much is each push charged and why?
3 units: 1 for the write, 2 saved as credit to pay for future copies of itself and a neighbor.
Why might amortized O(1) be unacceptable in real-time systems?
A single resize is O(n) — a latency spike — even though the average is constant.
What growth factor requirement guarantees amortized O(1) inserts?
Multiplicative (geometric) growth by any factor > 1; additive growth fails.

Recall Feynman: explain to a 12-year-old

Imagine filling a small box with toys. When it's full, you buy a box twice as big and move all toys over — that move is slow. But because each new box is double the last, you only move toys a few times even after hundreds of toys. So most of the time adding a toy is super fast, and the rare slow moves are tiny when you spread them out. On average, adding a toy is fast — that's "amortized O(1)."


Connections

  • Dynamic Arrays — primary use case of geometric resizing.
  • Hash Tables — rehashing on load-factor threshold uses the same argument.
  • Load Factor — triggers resize in open addressing.
  • Geometric Series — the math behind why doubling stays linear.
  • Big-O Notation — amortized is a flavor of asymptotic analysis.
  • Potential Method — formal accounting technique used here.
  • Stack with Multipop — another classic amortized analysis example.

Concept Map

defined as

is a

NOT

analyzed by

analyzed by

analyzed by

has

full triggers

+1 growth gives

doubling gives

total 3n so

charge 3 credits

explains

Amortized O 1

Total cost over n

Worst-case guarantee over sequence

Average-case with probability

Aggregate method

Accounting method

Potential method

Dynamic array / hash table

Fixed capacity

Resize copies O n

Total O n squared

Geometric series < 2n

Pre-pay future copies

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, amortized O(1) ka simple matlab hai: kabhi-kabhi ek operation mehnga (slow) hota hai, lekin agar woh bahut rarely hota hai, toh poore sequence pe average cost constant reh jaati hai. Jaise dynamic array (Python list, vector) mein jab array full ho jaaye toh usko bada karke saare elements copy karne padte hain — yeh O(n) ka kaam hai. Lekin trick yeh hai ki hum capacity ko double karte hain, +1 nahi.

Kyun double karna zaroori hai? Maan lo har baar +1 se badhao, toh copies ka total 1+2+3+...+n = n²/2 ho jaata hai — yeh O(n²) hai, har insert effectively O(n)! Par doubling se copies banti hain 1+2+4+8+... jo geometric series hai aur yeh 2n se kam rehti hai. Toh total kaam = n writes + 2n copies = 3n = O(n). Isko n se divide karo toh per operation sirf 3 units = O(1). Yahi magic hai geometric series ka.

Ek important baat — amortized O(1) ka matlab yeh nahi ki har operation fast hai. Resize wala ek single push toh genuinely slow (O(n)) hota hai, ek spike aata hai. Bas average constant hai. Aur isko average-case mat samajhna — average-case mein probability hoti hai, jabki amortized ek guaranteed worst-case hai poore sequence ke liye, chahe input kaisa bhi ho.

Hash table mein bhi yahi funda lagta hai: jab load factor (size/capacity) threshold cross kare, toh rehash karke table double kar dete hain. Same geometric argument se insert amortized O(1) ban jaata hai. Bas yaad rakho: "Double karo, add mat karo — mehnga cost spread ho jaata hai."

Go deeper — visual, from zero

Test yourself — Hashing

Connections