LearnThatStack Ace your next interview
Arrays, Strings & Hash Tables · question
Question 3 of 85

How does a dynamic array grow, and why is append amortized O(1)?

beginner
← All Arrays, Strings & Hash Tables questions
Re-explain
Visual ↓

A dynamic array grows by moving to a bigger block whenever the current one fills up. It allocates the new block, copies every element over, and releases the old one. The new block is a constant factor larger, often 1.5 or 2 times. Java's ArrayList grows by half each time, and CPython's list by about an eighth.

That copy costs O(n), so a single resize is not cheap. But resizes get rarer as the array grows. With doubling, going from 8 to 16 to 32 slots means the gaps between resizes keep doubling.

Spread the total copy work across every append, and each one averages out to constant time. That is what amortized O(1) means. An individual append occasionally spikes, but the long-run cost per append stays flat. Appending a million items in a row stays fast overall.

Rewriting in plainer words…

This answer doesn't lend itself to a diagram - it reads best . No credits were charged.

Why there's no diagram: “”

The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓

The diagram below the answer is the concept . Jump to it ↓

Tailored explanation · switch back to · ·
What should the new diagram focus on?
Guided practice for Arrays, Strings & Hash Tables One question at a time. Answer out loud, get graded, see what you missed.
See it - interactive diagram
How doubling keeps append amortized O(1)
Current blockdoubles when full
Countsrunning totals
length0
capacity2
total copied0
1step

A dynamic array stores its elements in one block. Capacity is how many slots the block has. Length is how many hold an element.

1 / 6

Each copy moves twice as many elements but makes room for twice as many appends, so the average cost per append stays constant. That is amortized O(1).

© LearnThatStack - diagrams may not be republished without permission.

Other questions have diagrams like this too. Sign in to ask for one where it's missing - it's free.

Create a free account
How well did you know this?
AI:

Saved in this browser - sign in to keep your review list.

How should your speech become text?

Listening… your words appear above as you speak - tap Stop when you're done.

Recording · cr - tap Stop & transcribe when you're done.

Transcribing with AI…

Voice:

Keep going - a few more words and AI can grade it.

Interview lens How interviewers actually use this question

Likely follow-ups

  • Can you show that n appends with doubling do only O(n) total copy work? The copies form a geometric series, 1 + 2 + 4 + ... up to n, which adds up to less than 2n, so the total stays linear.
  • Why grow by a constant factor instead of adding a fixed number of slots each time? Adding k slots means a copy every k appends. Total copying grows like n squared over k, so each append averages O(n).
  • What changes if you grow by 1.5x instead of 2x? A smaller factor leaves less capacity unused but resizes and copies more often. Both stay amortized O(1), only the constant changes.
  • An append can still stall on a big resize. When does that matter, and how do you avoid it? Latency-sensitive code feels the O(n) copy. If you know the final size, preallocate the capacity up front so no resize happens.
  • If elements get removed, when should the array shrink its capacity? Shrinking at half full thrashes when push and pop alternate at the boundary. Shrink to half when it drops to a quarter full.

What you can say

  1. When a dynamic array fills up, it allocates a bigger block, copies every element over, and frees the old one.
  2. The new block is a constant factor larger, often 1.5 or 2 times, and Java's ArrayList, for example, grows by half each time.
  3. That copy is O(n), so a single resize isn't cheap.
  4. But resizes get rarer as the array grows, so with doubling, going from 8 to 16 to 32 slots, the gap between resizes doubles each time.
  5. Spread the total copy work across every append and each one averages out to constant time, and that's what amortized O(1) means.
  6. The limit is that an individual append can still spike to O(n), so appends are fast over a long run, not every single time.

Weak answers to avoid

  • Says every append is O(1) Some appends copy the whole array and cost O(n). Say the cost is O(1) averaged over a sequence of appends, and explain where the expensive ones go.
  • Grows by a fixed number of slots Adding, say, 10 slots each time makes n appends cost O(n squared). The new capacity has to be a multiple of the current one.
  • Treats amortized as average case Amortized holds for every sequence of appends, with no luck about inputs. Average case, as with hash lookups, depends on the input. Keep the two apart.
  • Says resizes are rare and stops there Rare alone proves nothing. Show the gaps between resizes double, so total copying over n appends stays under 2n and each append costs O(1) on average.
Interview lens

Likely follow-ups, what you can say, and the weak answers to avoid.

Sign in free to open it Free account - the lens opens as soon as you're back.

Want a quick review of the fundamentals? See the Arrays, Strings & Hash Tables cheatsheet.

← Back to all Arrays, Strings & Hash Tables questions
Pro · $10/mo

74 of 85 Arrays, Strings & Hash Tables answers are in Pro.

Full answers, code samples, and AI explanations that go simpler or deeper. Cancel anytime.

  • Full answers + code
  • AI explanations, simpler or deeper
  • 1,000 AI credits / month
  • Cancel anytime