Unit 1 · Algorithms · Lesson 4 of 24
Linked lists
Builds on
Step 1: Learn the ideas
- Singly and doubly linked lists; sentinel and dummy nodes
- Iterative reversal with prev, curr and next
- Merging and splitting lists
- Fast and slow pointers: middle, cycle detection, cycle entry
- Gap pointers for the n-th node from the end
- Hash map plus doubly linked list (LRU cache)
- Recursion on lists and its stack cost
- Linked lists versus arrays: locality and allocation
Why it matters
Linked-list problems are short to state and unforgiving to code: one misordered assignment drops the rest of the list or creates a cycle. They test whether you can keep an invariant while mutating structure, the same skill you need for trees, graphs and concurrent data structures. Real systems use linked lists inside other structures: an LRU cache is a hash map plus a doubly linked list, and allocators, schedulers and kernels keep free lists and run queues.
Core ideas
Pattern: Linked-list pointer manipulation. Before you overwrite a pointer, save whatever it was keeping reachable. Iterative reversal holds three references with the invariant "prev heads the already-reversed prefix and curr heads the untouched suffix":
prev, curr = None, head
while curr:
nxt = curr.next # save the rest of the list
curr.next = prev # reverse one link
prev, curr = curr, nxt
return prev
Each node is visited once: O(n) time, O(1) space. The recursive version is shorter but uses O(n) stack, which can overflow on long lists.
Dummy heads. Allocate a sentinel node whose next is the real head. Inserting before the head, deleting the head and building a merged list then need no special case; return dummy.next. Merge Two Sorted Lists and Remove Nth Node From End are both simpler with one.
Pattern: Fast and slow pointers. Advance slow by one and fast by two.
- Middle: when
fastruns off the end,slowis at the middle. Which middle you get for even lengths depends on the loop condition, so test lengths 1 to 4. - Cycle detection (Floyd): inside a cycle
fastgains one node per step onslow, so they meet beforeslowcompletes a lap; without a cyclefastreaches null. - Cycle entry: let a be the distance from the head to the entry, b the distance from the entry to the meeting point and c the cycle length. Fast has walked twice as far as slow, so a + b is a multiple of c. Restart one pointer at the head and move both one step at a time: after a steps both stand on the entry.
- The same reasoning applies to any sequence x, f(x), f(f(x)), ... such as Happy Number or Find the Duplicate Number.
Gap pointers. For the n-th node from the end in one pass, move a lead pointer n steps ahead, then advance both until the lead reaches the end.
Composition. Many medium problems chain primitives. Reorder List is find the middle, reverse the second half, interleave. Palindrome Linked List is find the middle, reverse, compare, and ideally restore the list afterwards.
Lists with maps. A doubly linked list removes a known node and inserts at either end in O(1); a hash map from key to node supplies O(1) access. Together they make an LRU cache with O(1) get and put: move a node to the front on access, evict from the back.
Arrays versus lists. Lists win only when you already hold a reference to the splice point. Arrays win on indexing, memory overhead and cache locality; for small and medium sizes, shifting contiguous memory is often faster in practice than chasing pointers.
Common misconceptions
- "Inserting into a linked list is O(1)." Only once you hold a reference to the neighbor; finding the position is O(n).
- "Recursive list code is O(1) space." Each call adds a stack frame, so recursion over n nodes uses O(n) space.
- "Fast and slow pointers meet at the cycle entry." They meet somewhere inside the cycle; the entry needs the second phase from the head.
- "Edge cases are rare." Empty lists, single nodes, two nodes and changes at the head or tail are where bugs cluster; a dummy head removes many of them.
- "Linked lists beat arrays for insert-heavy code." Pointer chasing causes cache misses; measure before assuming the list wins.
How to approach it
Draw three or four nodes and every pointer change before coding, and say each invariant aloud. Use a dummy head whenever the head might change. Test the empty list, one node and two nodes explicitly. Interviewers watch for lost references and ask why Floyd's second phase finds the entry; at mid and senior levels expect to design the LRU structure and discuss what changes when several threads use it.
Suggested order
- 1Read MIT 6.006 Lecture 2 (Data Structures) for linked-list versus array sequences and the cost of each operation.
- 2Read MIT 6.006 Recitation 2 and compare its linked-list sequence implementation with how you would write one.
- 3Solve Reverse Linked List iteratively, then recursively, and state the space difference.
- 4Solve Merge Two Sorted Lists and Remove Nth Node From End of List using a dummy head.
- 5Solve Middle of the Linked List and Linked List Cycle, then Linked List Cycle II, writing out the distance argument for the entry.
- 6Solve Palindrome Linked List and Reorder List by composing find-middle, reverse and merge.
- 7Solve LRU Cache with a hash map and a doubly linked list, then Reverse Nodes in k-Group as the hardest relinking exercise.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
MIT 6.006 Introduction to Algorithms (Spring 2020)Start here
MIT OpenCourseWareSection: Lecture 2: Data Structures
Linked-list and dynamic-array sequences compared operation by operation, including where each is O(1) or O(n).
Open(opens in a new tab)Link responded, 5 Oct 2026MIT 6.006 Introduction to Algorithms (Spring 2020)
MIT OpenCourseWareSection: Recitation 2
Python implementations of array, linked-list and dynamic-array sequences to compare with your own pointer code.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Draw the pointers for three nodes before each problem and state the invariant. Do the first five on consecutive days until reversal, dummy heads and fast and slow pointers are automatic. Linked List Cycle II requires the written distance argument, not only code. LRU Cache is the design-style check; Reverse Nodes in k-Group is the hardest relinking exercise and good for review rotation.
- Reverse Linked ListLeetCode(opens in a new tab)Not attemptedLeetCode
- Merge Two Sorted ListsLeetCode(opens in a new tab)Not attemptedLeetCode
- Middle of the Linked ListLeetCode(opens in a new tab)Not attemptedLeetCode
- Linked List CycleLeetCode(opens in a new tab)Not attemptedLeetCode
- Remove Nth Node From End of ListLeetCode(opens in a new tab)Not attemptedLeetCode
- Linked List Cycle IILeetCode(opens in a new tab)Not attemptedLeetCode
- Palindrome Linked ListLeetCode(opens in a new tab)Not attemptedLeetCode
- Reorder ListLeetCode(opens in a new tab)Not attemptedLeetCode
- LRU CacheLeetCode(opens in a new tab)Not attemptedLeetCode
- Reverse Nodes in k-GroupLeetCode(opens in a new tab)Not attemptedLeetCode
- Add Two NumbersLeetCode(opens in a new tab)Not attemptedLeetCode
- Copy List with Random PointerLeetCode(opens in a new tab)Not attemptedLeetCode
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1What invariant do prev and curr satisfy during iterative reversal?
- Question 2Which middle node does your loop return for an even-length list, and how would you get the other?
- Question 3Why does restarting one pointer at the head find the cycle entry?
- Question 4What does a dummy head save you in a merge?
- Question 5Why does an LRU cache need a doubly linked list rather than a singly linked one?
- Question 6When is a linked list a worse choice than a dynamic array despite O(1) splicing?
You’re done when you can
- Write iterative list reversal from memory in under three minutes with no pointer errors.
- Explain why Floyd’s algorithm detects a cycle and how its second phase finds the entry.
- Solve Reorder List in under 25 minutes with O(1) extra space.
- Implement an LRU cache with O(1) get and put, testing eviction and updates to existing keys.
Finish the lesson
Unlocks next: Pattern recognition and mixed practice


