Home  /  Problems  /  Reverse Linked List Explained for Beginners: Three Pointers Walking in Single File
● Easy Linked List / Pointers

Reverse Linked List Explained for Beginners: Three Pointers Walking in Single File

Three pointers walking in single file. If pointer manipulation makes your brain slide off, this is the problem that finally makes it stick.

Start the walkthrough →
Asked at4+ companies
CiscoVMwareOracleGoldman Sachs
1

What a linked list actually looks like in memory

2

Why 'just swap the values' misses the point

3

The reframe: flip one arrow at a time (prev, curr, next)

4

The iterative solution, line by line — then the recursive one

Eleven months. 312 applications. Nine phone screens. Three of those nine screens — Cisco, an Oracle contractor role, and one bank that shall remain a bank — opened with some version of "reverse a linked list." The first time, I froze for four minutes of a forty-five minute call and never recovered. So this is reverse linked list explained for beginners, written the way I needed it explained when I was the person freezing.

This problem gets asked at 28+ companies and it is rated Easy, which is a word that does a lot of damage. Easy means "short to write once you see it." It does not mean "obvious the first time." Those are different things, and the gap between them is where people decide they aren't smart enough for this industry. They usually are. They've never been shown the mechanism.

What the problem is actually asking

You're handed the front of a chain. Each link holds a value and a pointer to the next link. The last link points at nothing. Your job: hand back the front of a chain that runs the other direction.

Given 1 -> 2 -> 3 -> None, return 3 -> 2 -> 1 -> None.

Here's the trap in how it's worded. "Reverse" makes you picture the whole list turning around at once, like a bus doing a three-point turn. That mental picture is unusable — you can't hold a whole list in your head and rotate it. The operation you actually perform is much smaller and happens one link at a time, and until you swap the picture, no amount of staring helps.

What a linked list actually looks like in memory

A linked list is not an array. There's no index. Nothing is stored next to anything else. What you have is a node — an object with two fields:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next   # a reference to another node, or None

So 1 -> 2 -> 3 is three separate objects scattered anywhere in memory, and the only thing holding them together is that node 1's next field points at node 2, and node 2's next points at node 3. Node 3's next is None, which is how you know the list ended.

The critical consequence: you can only move forward, and you can only see one node at a time. If you're standing on node 2, node 1 is unreachable. It's gone. There's no back button. Everything about this problem follows from that one constraint.

The obvious answer, and why it costs you the round

When I first saw this, my instinct was to build a new list. Walk to the last node, grab it, attach it to my new list. Walk to the second-to-last node, grab it, attach it. Repeat.

That works, and it is very slow. Because you can only move forward from the head, finding the last node means walking all n nodes. Finding the second-to-last means walking n-1. Then n-2. You end up doing roughly n²/2 steps. For a list of 100,000 nodes, that's about five billion pointer hops. A judge that allows a second of runtime will cut you off somewhere around node 3,000.

The other instinct is: copy every value into an array, reverse the array, then write the values back into the nodes. That's O(n) time, which passes. But it uses O(n) extra space, and more importantly it dodges the thing the question exists to test. The interviewer is not curious whether you can reverse an array. They want to watch you rewire pointers without dropping anything. Swapping values sidesteps the entire skill. In real systems, nodes carry payloads you don't own and can't safely copy — the pointers are the structure, and the structure is what you're being asked to change.

The reframe that unlocks it

Stop thinking about reversing a list. Think about flipping one arrow.

In 1 -> 2 -> 3 -> None, the arrow from 1 to 2 needs to become an arrow from 2 to 1. That's it. That's the whole operation, repeated.

Now the problem: the instant you point node 1's next at whatever came before it, you have destroyed the only reference to node 2. The rest of the list floats away and you cannot get it back. So before you flip anything, you save the next node in a temporary variable.

That gives you three pointers walking forward in single file:

Walk 1 -> 2 -> 3 -> None by hand. Start with prev = None and curr = node 1.

Pass save next_node flip curr.next = prev then prev then curr reversed so far
1 node 2 1 -> None node 1 node 2 1 -> None
2 node 3 2 -> 1 node 2 node 3 2 -> 1 -> None
3 None 3 -> 2 node 3 None 3 -> 2 -> 1 -> None

curr is now None, so the walk is over. prev is sitting on node 3 — the new head. Notice that prev starting at None is what makes the old head point at nothing, which is exactly right: the old first node has to become the new last node.

The solution

def reverseList(head):
    prev = None          # nothing comes before the first node yet
    curr = head          # start standing on the front of the list

    while curr is not None:
        next_node = curr.next   # 1. save the rest of the list before we break the link
        curr.next = prev        # 2. flip this one arrow backwards
        prev = curr             # 3. prev steps forward onto the node we finished
        curr = next_node        # 4. curr steps forward into the saved remainder

    return prev          # curr fell off the end; prev is the new head

In plain English: those four lines inside the loop always run in that order, and the order is the whole problem. Save, flip, advance, advance. Line 1 protects the future. Line 2 does the actual work. Lines 3 and 4 move both pointers one step down the chain. When curr walks off the end of the list, prev is standing on what used to be the last node, which is now the first.

Time: O(n) — every node is touched once. Space: O(1) — three variables, no matter how long the list is.

The recursive version exists and is shorter:

def reverseList(head):
    if head is None or head.next is None:
        return head              # empty list, or the last node: that's the new head
    new_head = reverseList(head.next)   # reverse everything after me
    head.next.next = head        # the node after me now points back at me
    head.next = None             # and I point at nothing (for now)
    return new_head

It's elegant and it's O(n) time, but it's O(n) stack space — a million-node list will blow the stack. Lead with the iterative one in an interview and mention the recursive one as an alternative. That sequencing is itself a signal.

The specific ways this goes wrong

Overwriting curr.next before saving it. You write curr.next = prev first, then reach for curr.next to advance — and it now points backward, so you walk into the part you already reversed and loop forever. Save next_node first, always.

Returning curr instead of prev. The loop only exits when curr is None. Returning it hands back an empty list and the tests fail in a way that looks mysterious for about ten minutes.

Initializing prev = head instead of None. Then the old head points at itself and you've built a cycle. The old head has to end up pointing at nothing.

Forgetting the empty list. If head is None, the loop body never runs and prev is still None, which is the correct answer. The iterative version handles it for free — but say that out loud rather than hoping nobody asks.

Reaching for recursion first. It reads as showing off, and then the follow-up question about memory usage arrives and you're defending a choice you didn't need to make.

What I can't tell you is whether any of this measures what it's supposed to. Being able to flip pointers under time pressure and being able to build software people rely on are not obviously the same skill, and nobody has published the study that settles it. So learn the mechanism until your hand moves without you — and keep asking why a company that will never ask you to hand-reverse a chain of nodes decided this was the thing that separates the hires from the rejections.

Watch out

Common mistakes graders flag