Skip to main content
Back to the DSA atlas
Linear structures Data structure Intro

Linked List Operations

Reverse, detect cycles, merge sorted lists. Linked lists test your pointer manipulation skills — every operation is about rewiring next pointers.

linked-listtwo-pointersrecursion

Interactive visualization

Use the controls to connect the idea to concrete operations before diving into the full write-up.

null
prev curr

Family

Linear structures

State that flows from one end to the other: lists, deques, stacks, and windows.

Builds on

Foundational

You can start here without another page first.

Unlocks

6 next topics

Use these follow-ups when you want to apply the current idea in a richer setting.

Learning paths

2

This topic appears in curated progressions so you can keep moving without guessing the next step.

What is a linked list?

A sequence of nodes where each node holds a value and a pointer to the next node. The last node points to null.

Node {
    val: T
    next: Node | null
}

Unlike arrays, linked lists don’t have random access. You can’t jump to index ii — you must walk from the head. But insertion and deletion at a known position are O(1)O(1) (just rewire pointers), compared to O(n)O(n) for arrays (shifting elements).

Reversal

The most fundamental linked list operation. Reverse the direction of all next pointers.

Iterative (3-pointer technique)

reverse(head):
    prev ← null
    curr ← head

    while curr is not null:
        next ← curr.next    // save next
        curr.next ← prev    // reverse pointer
        prev ← curr         // advance prev
        curr ← next         // advance curr

    return prev              // new head

Three pointers walk through the list in lockstep: prev, curr, next. At each step, you point curr.next backward to prev, then advance all three. When curr reaches null, prev is the new head.

Recursive

reverse(head):
    if head is null or head.next is null:
        return head

    new_head ← reverse(head.next)
    head.next.next ← head   // point successor back to us
    head.next ← null         // break forward link

    return new_head

The recursive version works from the tail backward. Each frame says: “reverse everything after me, then make my successor point back to me.” Elegant, but uses O(n)O(n) stack space.

Cycle detection (Floyd’s algorithm)

Also called the tortoise and hare algorithm. Use two pointers: slow advances by 1, fast advances by 2.

has_cycle(head):
    slow ← head
    fast ← head

    while fast is not null and fast.next is not null:
        slow ← slow.next
        fast ← fast.next.next

        if slow == fast:
            return true      // cycle detected

    return false             // no cycle

Why it works: if there’s a cycle, fast enters the cycle first. Slow enters later. Once both are in the cycle, fast approaches slow at a rate of 1 node per step (their distance decreases by 1 each iteration). They must eventually meet.

Why not just use a hash set? You could — store every visited node and check for duplicates. That’s O(n)O(n) space. Floyd’s uses O(1)O(1) space. In an interview, the follow-up is always “can you do it in constant space?”

Finding the cycle start

After slow and fast meet, reset one pointer to the head. Advance both by 1. Where they meet again is the start of the cycle.

find_cycle_start(head):
    slow ← head
    fast ← head

    // Phase 1: detect cycle
    while fast and fast.next:
        slow ← slow.next
        fast ← fast.next.next
        if slow == fast: break

    if fast is null or fast.next is null:
        return null  // no cycle

    // Phase 2: find start
    slow ← head
    while slow != fast:
        slow ← slow.next
        fast ← fast.next

    return slow

The math: if the cycle starts at distance dd from the head, and the meeting point is kk steps into the cycle, then d=cycle_lengthkd = \text{cycle\_length} - k. Resetting one pointer to the head and advancing both by 1 makes them meet at the cycle start.

Merge two sorted linked lists

Given two sorted linked lists, merge them into one sorted list. This is the merge step of merge sort on linked lists.

merge(l1, l2):
    dummy ← Node(0)
    tail ← dummy

    while l1 and l2:
        if l1.val <= l2.val:
            tail.next ← l1
            l1 ← l1.next
        else:
            tail.next ← l2
            l2 ← l2.next
        tail ← tail.next

    tail.next ← l1 or l2    // append remaining
    return dummy.next

Dummy node trick: using a dummy head node avoids special-casing the first insertion. The merged list starts at dummy.next.

Fast/slow pointer pattern

The tortoise-and-hare pattern extends beyond cycle detection:

ProblemSlow speedFast speedWhat it finds
Find middle12Middle node (slow when fast hits end)
Detect cycle12Cycle existence
Find k-th from endstart after k stepsstart from headk-th node from end
Check palindrome1 (+ reverse second half)2Find middle, then compare

Arrays vs linked lists

OperationArrayLinked list
Access by indexO(1)O(1)O(n)O(n)
Insert at frontO(n)O(n)O(1)O(1)
Insert at endO(1)O(1) amortizedO(1)O(1) with tail pointer
Insert at positionO(n)O(n)O(1)O(1) after traversal
Delete at positionO(n)O(n)O(1)O(1) after traversal
Cache localityExcellentPoor
Memory overheadNone1 pointer per node

In practice, arrays almost always win due to cache locality. Linked lists are useful when you need frequent insertion/deletion at arbitrary positions and you already have a reference to the node.

Complexity

OperationTimeSpace
ReversalO(n)O(n)O(1)O(1) iterative, O(n)O(n) recursive
Cycle detectionO(n)O(n)O(1)O(1)
Merge sortedO(n+m)O(n + m)O(1)O(1) (rewire pointers)
Find middleO(n)O(n)O(1)O(1)

Key takeaways

  • Reversal is the most fundamental operation — master the 3-pointer iterative technique (prev, curr, next) until it’s automatic
  • Floyd’s cycle detection uses O(1)O(1) space with two pointers at different speeds; always the interview follow-up after the hash set approach
  • The dummy node trick eliminates edge cases when building or merging lists — use it by default
  • Fast/slow pointer is a versatile pattern: find middle, detect cycles, check palindromes, find k-th from end
  • Linked lists rarely beat arrays in practice due to poor cache locality, but excel at frequent insertion/deletion at known positions

Practice problems

ProblemDifficultyKey idea
Reverse Linked List🟢 EasyIterative 3-pointer reversal pattern
Linked List Cycle🟢 EasyFloyd’s tortoise and hare for O(1) space detection
Merge Two Sorted Lists🟢 EasyDummy node with two-pointer merge
Remove Nth Node From End of List🟡 MediumTwo pointers with a gap of n nodes
LRU Cache🟡 MediumDoubly linked list plus hash map for O(1) access and eviction

Relation to other topics

  • Two pointers — fast/slow pointer on linked lists is a specialized form of the two-pointer technique used on arrays
  • Merge sort — merge sort is the ideal sorting algorithm for linked lists because it needs only sequential access and O(1)O(1) extra space
  • Hash maps — combining linked lists with hash maps (as in LRU Cache) gives O(1)O(1) ordered insertion, deletion, and lookup

What this enables

Once the current idea feels natural, these are the most useful next jumps.

Related directions

These topics live nearby conceptually, even if they are not direct prerequisites.

More from Linear structures

Stay in the same family when you want parallel variations of the same mental model.

Paths that include this topic

Follow one of these sequences if you want a guided next step instead of open-ended browsing.

Linear toolkit

Learn how sequence-shaped data unlocks queues, stacks, windows, and fast pointer manipulations.

Cache & distribution

Connect local eviction policy with distributed key placement and system-scale cache design.

From the blog

Pair the atlas with recent writing from the rest of the site when you want a broader engineering perspective alongside the topic graph.