Skip to content
Linked List Algorithms: Complete Guide with Examples

Linked List Algorithms: Complete Guide with Examples

Linked list problems are a core part of coding interviews because the data structure is simple and the mistakes are expensive. One lost pointer reference and the whole solution falls apart. The list only lets you move forward one node at a time, and there is no index arithmetic like there is with arrays. Every operation becomes a careful sequence of pointer updates, which is exactly what interviewers watch you manage under pressure.

Definition: a linked list is a chain of nodes, where each node stores a value and a pointer to the next node. The pattern is the set of pointer techniques that solve the most common questions: reversal, fast and slow pointers, dummy nodes, and merging.

Real-World Analogy

Imagine a scavenger hunt where each clue is written on a separate card. The card tells you where the next clue is hidden. To add a new clue in the middle of the hunt, you write one new card and change the location written on the previous card. Nobody else needs to touch anything.

A scavenger hunt with all clues on one page works differently. Adding a clue in the middle means rewriting every clue that follows. That is the difference between a linked list and an array. The array keeps everything in one ordered block, and the linked list scatters the pieces and connects them with pointers.

Visual Explanation

The node structure is the base of everything in this guide. Each node carries its value and a pointer to the next node, and the last pointer is null.

    graph LR
    H["head"] --> A["value: 3, next"]
    A --> B["value: 7, next"]
    B --> C["value: 1, next"]
    C --> D["value: 4, null"]
  

The most important mechanics to understand are how a reversal rewires the pointers, because reversal is a building block for several harder problems. The walk keeps a reference to the previous node, and each step redirects the current node’s pointer backward.

    graph LR
    A["prev = null, cur = node 1"] --> B["save node 2"]
    B --> C["node 1.next = null"]
    C --> D["prev = node 1, cur = node 2"]
    D --> E["save node 3"]
    E --> F["node 2.next = node 1"]
    F --> G["prev = node 2, cur = node 3"]
    G --> H["repeat to the end"]
    H --> I["return prev as the new head"]
  

Two things matter here. The saved next node is the only thing that keeps the walk alive, so it is captured before the pointer is overwritten. And the function returns the last node it visited, because that node becomes the head of the reversed list.

When to Use This Pattern

Use these pointer techniques when the problem has these characteristics:

  • The input is a singly linked list and the answer requires rearranging nodes by changing pointers. Since there is no random access, any solution that depends on indexing needs a different shape.
  • You need the middle node, the k-th node from the end, or a way to detect a cycle. Fast and slow pointers moving at different speeds answer all of these in one pass.
  • You are building a new list from one or two existing lists, or removing a node. A dummy head removes the special case for the first node and makes the code uniform.
  • The problem is a classic array problem, but the input is a linked list. The standard array solution often relies on indexing, so expect to convert it to a two-pass or pointer-based version.
  • You need insertions or deletions at a known position, and the cost of finding that position is the only cost. Pointer updates themselves are constant.

Complexity Analysis

The costs come from the only way to move through the structure. Every walk goes one node at a time, and there is no shortcut.

OperationTimeSpaceNotes
Access by index
O(N)
O(1)
Walk from the head, no random access
Search
O(N)
O(1)
Linear scan of the nodes
Insert at head
O(1)
O(1)
Repoint the head pointer
Insert at tail
O(N)
O(1)
Walk to the last node
Insert after a known node
O(1)
O(1)
Direct pointer update
Delete from tail
O(N)
O(1)
Walk to the second-to-last node

Anything position-based costs a walk because there is no index arithmetic. Once the right node is reached, pointer updates are constant time. Iterative algorithms use

O(1)
extra space because they keep only a few pointers. Recursive versions can cost
O(N)
stack space, which is why iterative solutions are preferred for long lists.

Memorizing complexity tradeoffs is half the battle. The other half is remembering them under pressure. Review this pattern with spaced repetition so the analysis becomes automatic by interview day.

Common Mistakes

All of these errors come from losing track of which pointer is still needed.

Overwriting the next pointer before saving it. In reversal and relinking problems, writing current.next = prev destroys the only reference to the rest of the list, and the walk dies after the first node. Before you assign to any .next field, state out loud where the pointer that was there is going.

Returning the wrong node after the head changes. Reversal and head insertions produce a new head, but the caller still holds the old one. If the function does not return the new head, the result is silently lost. Use a dummy node or an explicit return so the head is never special.

Forgetting that the fast pointer can be null. In fast and slow loops, fast.next.next dereferences fast.next. If the loop condition only checks fast, a two-node list throws a null pointer error. The condition must check both fast and fast.next.

Skipping the empty and single-node guards. Many solutions assume head.next exists. An empty list or a one-node list breaks the middle-finding and reversal code. A one-line guard at the top of the function prevents a confusing crash.

These mistakes are expensive because they look correct until they fail on a hidden test case. Our review decks flag exactly these edge cases and drill them until they are reflex. Add this pattern to your queue .

Related Patterns

  • Two Pointers . Fast and slow pointers on a linked list are the same idea as two pointers on an array, applied to a structure without index access.
  • Cycle Detection . Linked list cycles use Floyd’s algorithm, and the cycle problems live on the cycle detection pages because that pattern also covers graphs and arrays.
  • Recursion . Reversal and group reversal have recursive formulations. Iterative versions avoid the call stack, so they are the safer choice for long lists.

Next Steps

Once the concept is clear, the next step is making the code automatic. Check out the code templates for memorizable implementations in 6 languages, then work through the practice problems to apply the pattern to real interview questions.

Reading about a pattern once is not enough to own it in an interview. Practice this pattern with spaced repetition and turn recognition into recall.