Algorithms

ArrayList vs LinkedList

๐Ÿ“‹ Quick Reference

OperationArrayListLinkedListWinner
get(i)O(1)O(n)ArrayList
add(e) (end)O(1)*O(1)Tie
add(0, e) (front)O(n)O(1)LinkedList
add(i, e) (middle)O(n)O(n)ArrayList**
remove(0)O(n)O(1)LinkedList
remove(size-1)O(1)O(1)Tie
contains(e)O(n)O(n)ArrayList**
Memory per element~4 bytes~24 bytesArrayList

* Amortized (occasional resize) ** Better cache locality

One-liner: ArrayList for random access and memory efficiency; LinkedList only for frequent front insertions or queue/deque operations.

๐ŸŽฎ Interactive Visualizer

Compare how ArrayList and LinkedList handle the same operations:

Loading visualizer...
Try these operations:
  1. Random access (get) - see ArrayList's O(1) vs LinkedList's traversal
  2. Add at front - LinkedList just updates pointers
  3. Add at end - both are fast
  4. Add in middle - ArrayList shifts, LinkedList traverses then inserts

๐Ÿ”ง Internal Structure

ArrayList (Dynamic Array)

Contiguous memory block:
โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”
โ”‚ A โ”‚ B โ”‚ C โ”‚ D โ”‚ E โ”‚   โ”‚   โ”‚   โ”‚
โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜
  0   1   2   3   4   5   6   7
                      โ†‘
                    size=5, capacity=8

get(2): Direct calculation โ†’ array[2] โ†’ O(1)
add("F"): array[5] = "F", size++ โ†’ O(1)
add(0, "Z"): Shift all right, then insert โ†’ O(n)

LinkedList (Doubly-Linked)

Scattered nodes with pointers:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ prev: โˆ… โ”‚โ†โ”€โ”€โ†’โ”‚ prev    โ”‚โ†โ”€โ”€โ†’โ”‚ prev    โ”‚
โ”‚ data: A โ”‚    โ”‚ data: B โ”‚    โ”‚ data: C โ”‚
โ”‚ next    โ”‚โ†โ”€โ”€โ†’โ”‚ next    โ”‚โ†โ”€โ”€โ†’โ”‚ next: โˆ… โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ†‘                              โ†‘
   head                           tail

get(2): headโ†’nextโ†’next โ†’ O(n)
addFirst("Z"): Create node, update head pointer โ†’ O(1)
addLast("D"): Create node, update tail pointer โ†’ O(1)

๐Ÿ“Š Detailed Complexity Analysis

Time Complexity

OperationArrayListLinkedListNotes
get(index)O(1)O(n)AL: direct index; LL: traverse
set(index, e)O(1)O(n)Same as get
add(e)O(1)*O(1)AL: amortized; LL: has tail
add(index, e)O(n)O(n)AL: shift; LL: traverse + insert
addFirst(e)O(n)O(1)AL: shift all; LL: pointer update
remove(index)O(n)O(n)AL: shift; LL: traverse
removeFirst()O(n)O(1)AL: shift all; LL: pointer update
removeLast()O(1)O(1)Both have tail/size info
contains(e)O(n)O(n)AL faster (cache)
indexOf(e)O(n)O(n)AL faster (cache)
clear()O(n)O(n)Help GC
size()O(1)O(1)Both cache size

* Amortized O(1), worst case O(n) during resize

Space Complexity

AspectArrayListLinkedList
Element storage4-8 bytes/ref24+ bytes/node
Overhead (empty)~88 bytes~48 bytes
Overhead (1000 elem)~4-16 KB~24 KB
Memory localityContiguousScattered
Cache performanceExcellentPoor

โœ… When to Use Which

Choose ArrayList When

JAVA(19 lines)
Code
Loading syntax highlighter...

Choose LinkedList When

JAVA(22 lines)
Code
Loading syntax highlighter...

๐Ÿ”„ Common Operations Comparison

Adding Elements

JAVA(11 lines)
Code
Loading syntax highlighter...

Removing Elements

JAVA(11 lines)
Code
Loading syntax highlighter...

Iteration Performance

JAVA(20 lines)
Code
Loading syntax highlighter...

๐Ÿงฉ Real-World Patterns

Pattern 1: Stack

JAVA(5 lines)
Code
Loading syntax highlighter...

Pattern 2: Queue

JAVA(7 lines)
Code
Loading syntax highlighter...

Pattern 3: Frequent Middle Insertions

JAVA(5 lines)
Code
Loading syntax highlighter...

Pattern 4: LRU Cache

JAVA(16 lines)
Code
Loading syntax highlighter...

โš ๏ธ Common Pitfalls

1. Indexed Loop on LinkedList

JAVA(9 lines)
Code
Loading syntax highlighter...

2. Using LinkedList as General-Purpose List

JAVA(7 lines)
Code
Loading syntax highlighter...

3. Not Pre-sizing ArrayList

JAVA(8 lines)
Code
Loading syntax highlighter...

4. Assuming add() is Always Fast

JAVA(6 lines)
Code
Loading syntax highlighter...

๐ŸŽฏ Interview Practice

Test your ArrayList vs LinkedList knowledge with 10 curated interview questions:

๐ŸŽค List Comparison Interview Mode - Coming Soon


๐ŸŽค Interview Tips

Q: When would you use LinkedList over ArrayList?
"

LinkedList when you need O(1) insertions/removals at the front (queue operations), or when using Iterator.remove() frequently. In practice, ArrayList is better 95% of the time due to cache locality and lower memory overhead.

Q: Why is ArrayList faster for iteration even though both are O(n)?
"

ArrayList stores elements contiguously in memory, benefiting from CPU cache prefetching. LinkedList nodes are scattered in memory, causing cache misses on every access.

Q: What's the memory overhead of each?
"

ArrayList: ~4-8 bytes per reference (just the array slot). LinkedList: ~24 bytes per node (object header, prev pointer, next pointer, data reference). For large lists, ArrayList uses 3-6x less memory.

Q: Should you ever use LinkedList for a queue?
"

ArrayDeque is usually better for queues - it's faster and uses less memory. LinkedList is only useful if you need null elements (ArrayDeque doesn't allow null) or need to remove elements from the middle during iteration.


๐Ÿ“š Series Navigation

Series Complete! Return to Part 0: Overview

Visualizer: ListComparisonVisualizer from @tomaszjarosz/react-visualizers