LINEAR DATA STRUCTURES / ALGORITHM BRIEF

Singly linked list

A singly linked list is a chain of nodes where each node stores a value and a pointer to the next node.

BeginnerPhase 02 / Topic 1 of 8Mental modelComplexityEdge cases
01

Overview

A singly linked list is a chain of nodes where each node stores a value and a pointer to the next node. The list is identified by its head; the last node points to null. Unlike arrays, nodes are scattered in memory, so there is no index arithmetic: reaching the kth node means walking k steps.

The payoff is cheap structural change. Once you hold a reference to a node, inserting or removing the node after it is O(1), because you only rewire pointers. Almost every linked list interview problem is about rewiring pointers correctly without losing part of the list.

A treasure hunt

Each clue tells you where the next clue is hidden. To reach clue 5 you must follow clues 1 through 4. Adding a new clue between two others only requires changing what one clue points to; nothing else moves.

02

When to use it

  • Frequent insertions and deletions at the front, or next to a node you already hold.
  • You do not need random access by index.
  • Implementing stacks, queues, adjacency lists, or hash map buckets.
  • The problem gives you a ListNode head (most linked list interview questions).
03

Problem patterns it solves

Reverse pointers

Recognize it when: reverse all or part of a list, check palindrome, reorder.

  • 206. Reverse Linked List
  • 92. Reverse Linked List II
  • 25. Reverse Nodes in k-Group
  • 234. Palindrome Linked List
Dummy (sentinel) head

Recognize it when: the head itself might be removed or changed.

  • 203. Remove Linked List Elements
  • 21. Merge Two Sorted Lists
  • 82. Remove Duplicates from Sorted List II
Fast and slow pointers

Recognize it when: middle node, cycle detection, nth from the end.

  • 876. Middle of the Linked List
  • 141. Linked List Cycle
  • 19. Remove Nth Node From End of List
Merge and split

Recognize it when: merge sorted lists, sort a list, partition around a value.

  • 21. Merge Two Sorted Lists
  • 148. Sort List
  • 86. Partition List
  • 23. Merge k Sorted Lists
Digit lists

Recognize it when: numbers stored digit by digit; carry handling.

  • 2. Add Two Numbers
  • 445. Add Two Numbers II
04

Where it is used in real software

Hash map collision chains

Java's HashMap stores colliding entries in a linked list per bucket (converted to a red-black tree when a bucket grows past 8 entries).

Memory allocators

Free lists in malloc implementations link together available memory blocks so allocation and freeing are O(1).

Blockchains and Git

Each block or commit stores a pointer (hash) to its parent, forming a linked list back to the first one.

Undo history

Simple undo stacks and persistent data structures share list tails between versions without copying.

05

Key terms

Node
An object with val and next.
Head
Reference to the first node; null for an empty list.
Tail
The last node, whose next is null.
Dummy node
A placeholder before the head so edge cases at the head disappear.
Traversal
Following next pointers from head until null: O(n).
06

Reversing a list in place

  1. 1
    Start with prev = null, curr = head

    prev will become the new head; curr is the node being processed.

  2. 2
    Save next

    next = curr.next, because you are about to overwrite curr.next and would lose the rest of the list.

  3. 3
    Reverse the pointer

    curr.next = prev.

  4. 4
    Advance both

    prev = curr; curr = next.

  5. 5
    Return prev

    When curr is null, prev is the old tail, now the new head.

Reverse 1 -> 2 -> 3 -> 4
Step 1 / 5
curr
1
0
2
1
3
2
4
3

STEP 1prev = null, curr = 1. Links: 1 -> 2 -> 3 -> 4 -> null.

07

Remove all nodes with value 6 using a dummy head

head = 6 -> 1 -> 6 -> 2, val = 6

Step 1 / 5
Stepprevprev.nextActionList from dummy
1dummy6remove: dummy.next = 1dummy -> 1 -> 6 -> 2
2dummy1keep: prev = 1dummy -> 1 -> 6 -> 2
316remove: 1.next = 2dummy -> 1 -> 2
412keep: prev = 2dummy -> 1 -> 2
52nullstopreturn dummy.next = 1

NOWStep: 1 | prev: dummy | prev.next: 6 | Action: remove: dummy.next = 1 | List from dummy: dummy -> 1 -> 6 -> 2

The dummy node made removing the original head identical to removing any other node, so there is no special case.

08

Implementation

class ListNode {  constructor(val, next = null) {    this.val = val;    this.next = next;  }} function reverseList(head) {  let prev = null;  let curr = head;  while (curr) {    const next = curr.next; // save the rest    curr.next = prev;       // reverse the link    prev = curr;    curr = next;  }  return prev;} function removeElements(head, val) {  const dummy = new ListNode(0, head);  let prev = dummy;  while (prev.next) {    if (prev.next.val === val) prev.next = prev.next.next;    else prev = prev.next;  }  return dummy.next;} function mergeTwoLists(a, b) {  const dummy = new ListNode(0);  let tail = dummy;  while (a && b) {    if (a.val <= b.val) { tail.next = a; a = a.next; }    else { tail.next = b; b = b.next; }    tail = tail.next;  }  tail.next = a ?? b;  return dummy.next;} function addTwoNumbers(l1, l2) {  const dummy = new ListNode(0);  let tail = dummy, carry = 0;  while (l1 || l2 || carry) {    const sum = (l1?.val ?? 0) + (l2?.val ?? 0) + carry;    carry = Math.floor(sum / 10);    tail.next = new ListNode(sum % 10);    tail = tail.next;    l1 = l1?.next;    l2 = l2?.next;  }  return dummy.next;}
09

Complexity and performance

Access kth nodeO(k)

Must walk from the head.

Insert / delete at headO(1)

Rewire the head pointer.

Insert / delete after a known nodeO(1)

Only one pointer changes.

Delete a given node (singly)O(n)

You need the previous node, which requires a walk.

SearchO(n)

No binary search possible.

10

Trade-offs

vs arrays

Linked lists avoid shifting on insert, but each node carries pointer overhead and poor cache locality, so a simple scan is often several times slower than on an array.

Singly vs doubly

Singly linked lists use less memory but cannot move backward or delete a node in O(1) without its predecessor.

Recursive vs iterative

Recursive solutions are elegant but use O(n) stack space and can overflow on long lists.

11

Variants and related techniques

Doubly linked list

Adds a prev pointer for O(1) removal of any node and backward traversal.

Circular linked list

The tail points back to the head; used for round-robin scheduling and the Josephus problem.

Skip list

Multiple levels of forward pointers give O(log n) search; used in Redis sorted sets.

12

Common mistakes

  • Losing the rest of the list.

    Fix: Save curr.next before overwriting it.

  • Null pointer errors at the end.

    Fix: Check curr and curr.next before dereferencing; with fast pointers check fast && fast.next.

  • Special-casing the head.

    Fix: Use a dummy node and return dummy.next.

  • Returning the old head after reversing.

    Fix: Return prev, the new head.

13

Interview questions

How do you find the middle of a linked list in one pass?

Move slow one step and fast two steps. When fast reaches the end, slow is at the middle.

Why use a dummy node?

It gives every real node a predecessor, so inserting or deleting at the head uses the same code as anywhere else.

Can you delete a node given only that node?

If it is not the tail, copy the next node's value into it and bypass the next node. This is O(1) but changes node identity.

14

Practice problems

ProblemDifficultyWhat it trains
206. Reverse Linked ListEasyIterative and recursive reversal.
21. Merge Two Sorted ListsEasyDummy node and tail pointer.
203. Remove Linked List ElementsEasyDummy head removal.
2. Add Two NumbersMediumCarry propagation.
92. Reverse Linked List IIMediumPartial reversal.
25. Reverse Nodes in k-GroupHardReverse in blocks.