Module 4: Linked Lists·Tutorial 7 of 23 (Step 4.1)
All Tutorials·DSA Roadmap·5 Problems · ~14 hrs

4.1 Linked Lists & LRU Cache

Understand what a Node is, why Linked Lists exist compared to Arrays, how to rewire pointers without losing the list, and how to build an LRU Cache.

01 Read the story: What & Why
02 Follow the drawing: Visual stepper
03 Practice code: 4 languages + problems

1. What Is a Linked List?

An Array stores all of its items side-by-side in one single block of memory. A Linked List does the exact opposite: its items can live anywhere in memory, connected like a treasure hunt where each box (called a Node) holds two things:

  1. val: The value stored inside this node (e.g., 10).
  2. next: A pointer (memory address arrow) pointing to the next node in the chain, or null (None) at the end.

In a Doubly Linked List, each node also holds a prev arrow pointing backward to the previous node.

OperationDynamic Array (list / vector)Singly Linked List (head -> next)Doubly Linked List (prev <-> next)
Read k-th item (arr[k])O(1) (Instant math)O(N) (Must walk k arrows)O(N) (Must walk k arrows)
Insert / Delete at Front (head)O(N) (Shifts all items)O(1) (Rewire 1 pointer)O(1) (Rewire 2 pointers)
Delete a Given Node curr in MiddleO(N) (Shifts items left)O(N) (Must find node before curr)O(1) (curr.prev.next = curr.next)
Extra Memory Overhead per Item0 extra bytes1 pointer (8 bytes)2 pointers (16 bytes — used in LRU Cache!)
Visual: Linked List Node Structure [val | next] & In-Place Reversal
dummy0• nexthead10• nextcurr20• nextnxt30• nextReversal: 1) nxt = curr.next 2) curr.next = prev 3) prev = curr 4) curr = nxt

2. Why Do We Need Linked Lists & How Do They Work?

The Pain With Arrays (O(N) Middle Insert/Delete)

In an Array, inserting or deleting an item at the front or middle forces every subsequent item to shift over in memory (O(N)).

Why Linked Lists Win at Splicing (O(1))

If you already have a pointer to a node curr in a Linked List:

  • Inserting a new node right after curr takes O(1) time: Just point new_node.next = curr.next, and then curr.next = new_node. Zero items shift in memory!
  • Deleting the node after curr takes O(1) time: Just bypass it with curr.next = curr.next.next.
  • The Trade-Off: You lose O(1) index lookup (arr[5]). To reach the 5th node in a Linked List, you must start at head and follow .next 5 times (O(N)).

3. Basic Operations & Walkthroughs (All 4 Languages)

class ListNode:
  def __init__(self, val=0, next=None):
      self.val = val
      self.next = next

# 1. Build 10 -> 20 -> 30
head = ListNode(10, ListNode(20, ListNode(30)))

# 2. Traverse from head to null -> O(N)
curr = head
while curr:
  # read curr.val
  curr = curr.next

# 3. Insert 15 right after head (10) -> O(1)
new_node = ListNode(15)
new_node.next = head.next
head.next = new_node      # 10 -> 15 -> 20 -> 30

# 4. Delete the node after head (removes 15) -> O(1)
head.next = head.next.next  # back to 10 -> 20 -> 30

4. The 4 Essential Interview Patterns

Pattern 1: In-Place Pointer Reversal (prev, curr, nxt)

To reverse a linked list in O(1) memory, walk curr forward while flipping each .next arrow backward toward prev. Golden Rule: Always save nxt = curr.next before you overwrite curr.next = prev, or you lose the rest of the list!

The Hand-Drawn Step-by-Step Walkthrough
Step 1 / 3

Interactive Step-by-Step Trace: In-Place Linked List Reversal (3 Pointers)

Watch how prev, curr, and next_node flip each arrow one at a time:

Step 1: Save next_node = curr.next before breaking the link
prevNone
curr10 →curr
next_node20 →saved!
tail30 → None
next_node = curr.next // Save node 20 so we don't lose the rest of the list!

If you overwrite curr.next first without saving curr.next, node 20 and 30 are lost forever.

✎ Remember this: Always save next_node FIRST before rewiring curr.next.

Pattern 2: Dummy Sentinel Node (dummy = ListNode(0, head))

Whenever the head of the list might change (merging lists, deleting the 1st node), create a dummy node before head. Attach everything to dummy, and return dummy.next!

Pattern 3: Fast & Slow Pointers (Floyd's Cycle & Middle Detection)

Move slow by 1 step and fast by 2 steps:

  • When fast reaches null, slow is at the exact middle of the list.
  • If there is a cycle, fast laps slow and they collide (slow == fast) in O(N) time and O(1) memory.
Visual: Fast (2x) & Slow (1x) Pointers — Cycle Detection & Middle Finding
12345slow (middle!)fast (at end)When fast reaches the end, slow is at the exact middle. In a cycle, fast laps slow!

Pattern 4: LRU Cache (Hash Map + Doubly Linked List)

To get O(1) lookup AND O(1) recency updates:

  • Store key -> Node in a Hash Map for instant O(1) lookup.
  • Connect all nodes in a Doubly Linked List between dummy HEAD (LRU) and TAIL (MRU) so any accessed node can be unlinked from the middle and moved to TAIL in O(1) time!
Visual: LRU Cache Architecture (Hash Map O(1) Lookup + Doubly Linked List O(1) Reorder)
Hash Map (key → Node*)key 1 ──► Node(1)key 2 ──► Node(2)HEAD (LRU)⇄Node(1)⇄Node(2)
Pattern: 3-Pointer In-Place Reversal & Fast/Slow Middle Finder

Use 3 pointers whenever reversing a full list or sublist (like the second half of a Palindrome or Reorder List) in O(1) memory.

# 1. Find Middle (slow stops at middle):
slow = fast = head
while fast and fast.next:
  slow = slow.next
  fast = fast.next.next

# 2. Reverse from slow onward:
prev, curr = None, slow
while curr:
  nxt = curr.next
  curr.next = prev
  prev = curr
  curr = nxt
Operation / PatternTimeSpaceNotes
Access k-th ElementO(N)O(1)Must walk k pointers from head
Insert / Delete After Known NodeO(1)O(1)Rewires 2 pointers; no shifting
In-Place Reversal / Cycle DetectionO(N)O(1)Uses 2 or 3 pointer variables
LRU Cache (get & put)O(1)O(capacity)Hash Map + Doubly Linked List

5. Practice On Your Own (Curated Submodule Problems)

0 / 5 Solved
StatusProblemDifficultyComplexityHint?Links & Notes
Reverse Linked List
In-Place Pointer Reversal
Easy
T: O(N)
S: O(1)
Solve
Merge Two Sorted Lists
Dummy Sentinel Node
Easy
T: O(M + N)
S: O(1)
Solve
Linked List Cycle
Fast & Slow Pointers (Cycle & Middle)
Easy
T: O(N)
S: O(1)
Solve
Remove Nth Node From End of List
Dummy Sentinel Node
Medium
T: O(N)
S: O(1)
Solve
LRU Cache
Hash Map + Doubly Linked List (LRU Cache)
Medium
T: O(1)
S: O(capacity)
Solve