Intuition The big picture (WHY this exists)
Some operations are occasionally expensive but usually cheap . If you bound them by their worst single case , you lie about the truth. Example: a dynamic array's push is O ( 1 ) O(1) O ( 1 ) almost always, but once in a while it doubles and copies everything (O ( n ) O(n) O ( n ) ). Amortized analysis asks: over a whole sequence of operations, what is the average cost per operation — guaranteed, not probabilistic?
Key word: guaranteed . Amortized ≠ \neq = average-case. There is no randomness . We promise that any sequence of m m m operations costs at most m ⋅ ( amortized cost ) m \cdot (\text{amortized cost}) m ⋅ ( amortized cost ) , in the absolute worst case.
Definition Amortized cost
Given a sequence of m m m operations with total actual cost T ( m ) T(m) T ( m ) , the amortized cost per operation is any value c ^ \hat{c} c ^ such that
∑ i = 1 m c ^ i ≥ ∑ i = 1 m c i (actual cost) \sum_{i=1}^{m} \hat{c}_i \;\ge\; \sum_{i=1}^{m} c_i \quad \text{(actual cost)} ∑ i = 1 m c ^ i ≥ ∑ i = 1 m c i (actual cost)
We then report c ^ = 1 m ∑ c ^ i \hat{c} = \frac{1}{m}\sum \hat{c}_i c ^ = m 1 ∑ c ^ i . The amortized bound is honest because the left side upper-bounds the real total work.
There are three methods to find c ^ \hat{c} c ^ . All give the same total bound; they differ in how you account .
Compute the total cost T ( m ) T(m) T ( m ) of any sequence of m m m operations directly, then divide: amortized cost = T ( m ) / m = T(m)/m = T ( m ) / m . Every operation gets the same amortized cost. Simplest to think about, weakest when operations differ.
Worked example Dynamic array (table doubling),
m m m pushes
HOW: Start with capacity 1. When full, allocate double and copy.
Cheap part: each push writes 1 element ⇒ \Rightarrow ⇒ m m m writes total.
Expensive part (copies): we copy when size hits 1 , 2 , 4 , 8 , … 1, 2, 4, 8, \dots 1 , 2 , 4 , 8 , … The copy costs are 1 + 2 + 4 + ⋯ + 2 k 1+2+4+\dots+2^{k} 1 + 2 + 4 + ⋯ + 2 k where 2 k ≤ m 2^k \le m 2 k ≤ m .
Why this step? The copy sizes form a geometric series. The crucial fact:
1 + 2 + 4 + ⋯ + 2 k = 2 k + 1 − 1 < 2 m . 1+2+4+\dots+2^k = 2^{k+1}-1 < 2m. 1 + 2 + 4 + ⋯ + 2 k = 2 k + 1 − 1 < 2 m .
Total: T ( m ) ≤ m + 2 m = 3 m T(m) \le m + 2m = 3m T ( m ) ≤ m + 2 m = 3 m .
Amortized: c ^ = T ( m ) / m ≤ 3 = = = O ( 1 ) = = \hat{c} = T(m)/m \le 3 = ==O(1)== c ^ = T ( m ) / m ≤ 3 === O ( 1 ) == per push.
Common mistake Steel-man: "doubling copies
n n n elements, so push is O ( n ) O(n) O ( n ) amortized"
Why it feels right: the single expensive push really does copy n n n elements — you can watch it happen.
The fix: that O ( n ) O(n) O ( n ) copy happens only once every n n n pushes . The expensive events are rare and geometrically spaced , so the copies sum to < 2 m <2m < 2 m total, not m ⋅ n m\cdot n m ⋅ n . Cost averaged over the gap between doublings is constant.
Charge each operation an amortized cost c ^ \hat c c ^ that may be more than its real cost. The surplus is stored as credit on data-structure elements. Later, expensive operations spend stored credit instead of charging the user. Rule that makes it valid:
total credit = ∑ ( c ^ i − c i ) ≥ 0 at all times. \text{total credit} = \sum(\hat c_i - c_i) \ge 0 \quad \text{at all times.} total credit = ∑ ( c ^ i − c i ) ≥ 0 at all times.
If the bank never goes negative, ∑ c ^ ≥ ∑ c \sum \hat c \ge \sum c ∑ c ^ ≥ ∑ c , so the bound is honest.
Worked example Dynamic array, accounting style
HOW: Charge c ^ = 3 \hat c = 3 c ^ = 3 per push. Real cost of a non-resizing push is 1 1 1 .
Spend $1 to place the new element.
Store $1 on the new element (to pay to move itself later).
Store $1 on an older element that has no credit yet.
Why this step? When the array doubles from n n n to 2 n 2n 2 n , exactly the n n n elements present must be copied. The last n n n pushes each saved $2, covering both the new half and the old half. So every copy is prepaid — credit never goes negative.
Amortized: c ^ = 3 = O ( 1 ) \hat c = 3 = O(1) c ^ = 3 = O ( 1 ) . ✓ matches aggregate.
Worked example Binary counter increment (k-bit)
Cost of increment = number of bits flipped.
Accounting: charge $2 per increment. Setting a bit 0 → 1 0\to1 0 → 1 costs \backslash1 and stores \ 1 on that bit. When a bit flips 1 → 0 1\to0 1 → 0 later (during a carry), pay with **its own stored %1 ∗ ∗ . ∗ ∗ W h y v a l i d : ∗ ∗ e v e r y 1**.
**Why valid:** every 1 ∗ ∗ . ∗ ∗ W h y v a l i d : ∗ ∗ e v er y 1 bit always carries exactly \ 1 of credit, so all the cascading carries are prepaid. Amortized cost of increment = = = O ( 1 ) = = = ==O(1)== === O ( 1 ) == , even though one increment can flip k k k bits.
Intuition WHAT (the most powerful, most reusable)
Define a potential function Φ ( D ) \Phi(D) Φ ( D ) mapping a data-structure state D D D to a real number ("stored energy"). The amortized cost of an operation is its actual cost plus the change in potential :
c ^ i = c i + Φ ( D i ) − Φ ( D i − 1 ) \boxed{\hat c_i = c_i + \Phi(D_i) - \Phi(D_{i-1})} c ^ i = c i + Φ ( D i ) − Φ ( D i − 1 )
WHY this works (derive the telescoping):
∑ i = 1 m c ^ i = ∑ i = 1 m c i + ( Φ ( D m ) − Φ ( D 0 ) ) . \sum_{i=1}^m \hat c_i = \sum_{i=1}^m c_i + \big(\Phi(D_m) - \Phi(D_0)\big). ∑ i = 1 m c ^ i = ∑ i = 1 m c i + ( Φ ( D m ) − Φ ( D 0 ) ) .
The potential differences telescope. If we ensure Φ ( D m ) ≥ Φ ( D 0 ) \Phi(D_m) \ge \Phi(D_0) Φ ( D m ) ≥ Φ ( D 0 ) (usually Φ ≥ 0 \Phi\ge0 Φ ≥ 0 and Φ ( D 0 ) = 0 \Phi(D_0)=0 Φ ( D 0 ) = 0 ), then
∑ c ^ i ≥ ∑ c i . \sum \hat c_i \ge \sum c_i. ∑ c ^ i ≥ ∑ c i .
So the amortized total upper-bounds the real total — honest.
Worked example Dynamic array via potential — derive
Φ \Phi Φ from scratch
Let n n n = number of elements, s s s = capacity. We want Φ \Phi Φ that grows as the table fills so it can pay for a copy.
Choose Φ = 2 n − s \Phi = 2n - s Φ = 2 n − s when n ≥ s / 2 n \ge s/2 n ≥ s /2 (and ≥ 0 \ge 0 ≥ 0 , which holds since n ≥ s / 2 ⇒ 2 n ≥ s n\ge s/2 \Rightarrow 2n\ge s n ≥ s /2 ⇒ 2 n ≥ s ).
Non-resizing push (n → n + 1 n \to n+1 n → n + 1 , s s s unchanged):
c ^ = 1 ⏟ c i + ( 2 ( n + 1 ) − s ) − ( 2 n − s ) = 1 + 2 = 3. \hat c = \underbrace{1}_{c_i} + \big(2(n+1)-s\big)-\big(2n-s\big) = 1 + 2 = 3. c ^ = c i 1 + ( 2 ( n + 1 ) − s ) − ( 2 n − s ) = 1 + 2 = 3.
Why: push adds 2 units of potential (saving for the future) at cost of 1 real write.
Resizing push (table full: n = s n=s n = s , copy n n n , then s → 2 s s\to 2s s → 2 s , n → n + 1 n\to n+1 n → n + 1 ):
Actual cost c i = n + 1 c_i = n+1 c i = n + 1 (copy n n n + insert 1).
Before: Φ = 2 n − s = 2 n − n = n \Phi = 2n - s = 2n - n = n Φ = 2 n − s = 2 n − n = n .
After: Φ = 2 ( n + 1 ) − 2 s = 2 ( n + 1 ) − 2 n = 2 \Phi = 2(n+1) - 2s = 2(n+1)-2n = 2 Φ = 2 ( n + 1 ) − 2 s = 2 ( n + 1 ) − 2 n = 2 .
c ^ = ( n + 1 ) + ( 2 − n ) = 3. \hat c = (n+1) + (2 - n) = 3. c ^ = ( n + 1 ) + ( 2 − n ) = 3.
Why this is the punchline: the big real cost n + 1 n{+}1 n + 1 is cancelled by the potential dropping by n − 2 n{-}2 n − 2 . The stored energy pays the copy. c ^ = O ( 1 ) \hat c = O(1) c ^ = O ( 1 ) — third method, same answer. ✓
Recall Feynman: explain to a 12-year-old
Imagine a piggy bank. Every time you do a small chore you put in 3 coins but the chore only "costs" 1 coin of effort. The extra 2 coins pile up. Once in a while a HUGE chore appears (cleaning the whole room). Instead of crying, you smash the piggy bank — and surprise, you saved exactly enough coins to pay for it! So even though one chore looked giant, on average every chore only ever cost you 3 coins. That averaged-but-guaranteed price is the amortized cost , and the piggy bank is the potential function .
Mnemonic Remember the three methods
"A-A-P" → A ggregate (Add all, divide), A ccounting (bank Account / credit), P otential (Physics energy Φ \Phi Φ ).
And the master equation: "Actual plus Delta-Phi" — c ^ = c + Δ Φ \hat c = c + \Delta\Phi c ^ = c + ΔΦ .
Amortized cost is which kind of average — over inputs or guaranteed over a sequence? Guaranteed worst-case over any sequence of operations; there is NO probability/randomness involved.
Aggregate method in one line Compute total cost
T ( m ) T(m) T ( m ) of
m m m ops directly, then amortized cost
= T ( m ) / m = T(m)/m = T ( m ) / m (same for every op).
Why is a dynamic array push O ( 1 ) O(1) O ( 1 ) amortized despite O ( n ) O(n) O ( n ) copies? Copies happen geometrically rarely; total copy work
= 1 + 2 + ⋯ + 2 k < 2 m =1+2+\dots+2^k<2m = 1 + 2 + ⋯ + 2 k < 2 m , so total
T ( m ) < 3 m T(m)<3m T ( m ) < 3 m .
Accounting method validity condition Total stored credit
∑ ( c ^ i − c i ) \sum(\hat c_i-c_i) ∑ ( c ^ i − c i ) must stay
≥ 0 \ge 0 ≥ 0 at all times (bank never goes negative).
Master equation of the potential method c ^ i = c i + Φ ( D i ) − Φ ( D i − 1 ) \hat c_i = c_i + \Phi(D_i)-\Phi(D_{i-1}) c ^ i = c i + Φ ( D i ) − Φ ( D i − 1 ) (actual cost plus change in potential).
Why does the potential method give a valid upper bound? Telescoping:
∑ c ^ i = ∑ c i + Φ ( D m ) − Φ ( D 0 ) \sum\hat c_i=\sum c_i+\Phi(D_m)-\Phi(D_0) ∑ c ^ i = ∑ c i + Φ ( D m ) − Φ ( D 0 ) ; if
Φ ( D m ) ≥ Φ ( D 0 ) \Phi(D_m)\ge\Phi(D_0) Φ ( D m ) ≥ Φ ( D 0 ) then
∑ c ^ i ≥ ∑ c i \sum\hat c_i\ge\sum c_i ∑ c ^ i ≥ ∑ c i .
Two requirements for a good potential function Φ ( D 0 ) = 0 \Phi(D_0)=0 Φ ( D 0 ) = 0 and
Φ ( D i ) ≥ 0 \Phi(D_i)\ge0 Φ ( D i ) ≥ 0 for all
i i i .
Potential function used for table doubling Φ = 2 n − s \Phi=2n-s Φ = 2 n − s (n = #elements, s = capacity), giving
c ^ = 3 \hat c=3 c ^ = 3 per push.
Amortized cost of incrementing a binary counter O ( 1 ) O(1) O ( 1 ) — charge $2: \backslash
1 to set a bit, \ 1 stored on it to pay its future
1 → 0 1\to0 1 → 0 flip.
Difference: amortized vs average-case complexity Amortized = deterministic guarantee over a sequence; average-case = expectation over a random distribution of inputs.
Dynamic Arrays / Table Doubling — the canonical amortized example.
Big-O, Big-Omega, Big-Theta — amortized bounds are still expressed in asymptotic notation.
Disjoint Set Union (Union-Find) — path compression + union by rank analyzed via potential.
Splay Trees — O ( log n ) O(\log n) O ( log n ) amortized via a potential function.
Fibonacci Heaps — decrease-key O ( 1 ) O(1) O ( 1 ) amortized using potential of marked nodes.
Geometric Series — the summation engine behind the aggregate method.
Average-case with randomness
Sum c-hat >= Sum actual cost
Intuition Hinglish mein samjho
Dekho, amortized analysis ka basic idea simple hai: kuch operations kabhi-kabhi bahut mehenge hote hain, par mostly sasta. Jaise dynamic array me push — normally O ( 1 ) O(1) O ( 1 ) , lekin jab array full ho jaye to wo double hoke saare elements copy karta hai, jo O ( n ) O(n) O ( n ) lagta hai. Agar hum sirf us ek mehenge case se dar ke "push is O ( n ) O(n) O ( n ) " bol de, to ye galat hai. Kyunki wo mehenga case sirf kabhi-kabhi aata hai. Amortized analysis poori sequence pe average nikaalta hai — aur ye guarantee hota hai, koi probability nahi (yahi average-case se difference hai).
Teen methods hain, yaad rakho A-A-P . Aggregate : total cost T ( m ) T(m) T ( m ) nikaalo, divide by m m m . Array me copies 1 + 2 + 4 + ⋯ < 2 m 1+2+4+\dots < 2m 1 + 2 + 4 + ⋯ < 2 m , total < 3 m < 3m < 3 m , to per push ≤ 3 = O ( 1 ) \le 3 = O(1) ≤ 3 = O ( 1 ) . Accounting (banker's): har push pe $3 \text{ charge karo jabki real cost }1 hai. Extra \ 2 ko credit ki tarah elements pe store karo — jab copy ka time aaye, wo stored credit se pay ho jaata hai, user se extra nahi maangte.
Potential method sabse powerful aur reusable hai. Ek function Φ \Phi Φ define karo jo data structure me "stored energy" represent kare. Formula: c ^ = c + Δ Φ \hat c = c + \Delta\Phi c ^ = c + ΔΦ — actual cost plus potential ka change. Cheap operations Φ \Phi Φ ko badhate hain (saving), aur mehenga operation Φ \Phi Φ ko gira deta hai (pay out), to c ^ \hat c c ^ chhota reh jaata hai. Array ke liye Φ = 2 n − s \Phi = 2n - s Φ = 2 n − s lo — har case me c ^ = 3 \hat c = 3 c ^ = 3 aata hai. Teeno methods ka answer same: O ( 1 ) O(1) O ( 1 ) .
Ye matter karta hai kyunki real interviews aur real systems me (DSU, splay trees, Fibonacci heaps) tum worst-single-case se bound loge to bahut loose answer milega. Amortized se tight aur honest bound milta hai — "average per operation, guaranteed". Piggy bank wala example yaad rakho: chhote chores me coins jama karo, bada chore aaye to gullak phod ke pay kar do.