Guides

How to Reverse a Linked List (Iterative and Recursive)

How to reverse a linked list iteratively and recursively, with Python and Java code, complexity analysis, and interview tips.

Practical guideInformational7 min read
How to Reverse a Linked List (Iterative and Recursive)

Put this into action

Turn this guide into better conversations with Articuler

Use this guide as the research layer, then turn the next step into a live networking workflow: search by intent, prep for the conversation, and send outreach that is built for replies.

Try the Articuler workflow

To reverse a singly linked list, you walk the list once and flip every next pointer so each node points to its predecessor instead of its successor. The iterative three-pointer method (prev, curr, next) does this in O(n) time and O(1) space and is the answer interviewers expect. The recursive method is also O(n) time but costs O(n) space because of the call stack. Master both, plus the common ways people get it wrong, and you can solve "reverse a linked list" cleanly on a whiteboard in under five minutes.

This guide covers the singly linked list itself, both approaches with runnable code, a complexity comparison, the common mistakes, and how to narrate your solution in an interview.

What a Singly Linked List Is

A singly linked list is a linear sequence where each node holds two things: a piece of data and a reference to the next node. Per Wikipedia's linked list article, "each node contains data, and a reference (in other words, a link) to the next node in the sequence." The last node's next is null, which marks the end of the list.

That structure is why reversing feels tricky at first. Unlike an array, a linked list gives you no random access: you move forward one node at a time from a single entry point, the head. So to reverse the list, you re-thread the pointers as you go without losing your place. Here is the node definition in Python and Java:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class ListNode {
    int val;
    ListNode next;
    ListNode(int val) { this.val = val; }
}

The whole task of "how to reverse a linked list" comes down to this: for a list 1 -> 2 -> 3 -> null, produce 3 -> 2 -> 1 -> null and return the new head, 3.

The Iterative Approach (Three Pointers)

The iterative solution is the one to reach for first. You keep three references while you walk the list:

  • prev — the node you already reversed (starts as null)
  • curr — the node you are reversing right now (starts at head)
  • next — a temporary save of curr.next so you don't lose the rest of the list

On each step you save curr.next, point curr.next back at prev, then slide all three pointers forward. When curr falls off the end, prev is the new head.

def reverse_iterative(head):
    prev = None
    curr = head
    while curr:
        next_node = curr.next   # save the rest of the list
        curr.next = prev        # reverse this node's pointer
        prev = curr             # advance prev
        curr = next_node        # advance curr
    return prev                 # prev is the new head
ListNode reverseIterative(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode nextNode = curr.next;  // save the rest
        curr.next = prev;               // reverse pointer
        prev = curr;                    // advance prev
        curr = nextNode;                // advance curr
    }
    return prev;                        // new head
}

The order of those four lines is not negotiable. If you overwrite curr.next before saving it, the tail vanishes and you strand every following node. Save first, reverse second.

This runs in a single pass, so it is O(n) time, and it only ever holds three pointers, so it is O(1) space. That constant space is why interviewers and production codebases prefer it.

The Recursive Approach

The recursive version reverses the list by trusting recursion to handle everything past the current node, then fixing up the two-node link at the current frame. You recurse to the tail, which becomes the new head, and unwind back toward the front. This mirrors how the Python tutorial on data structures frames recursive list processing — solve the small tail case, then compose.

def reverse_recursive(head):
    if head is None or head.next is None:
        return head                    # base case: empty or single node
    new_head = reverse_recursive(head.next)
    head.next.next = head              # make the next node point back
    head.next = None                   # cut the old forward link
    return new_head
ListNode reverseRecursive(ListNode head) {
    if (head == null || head.next == null) return head;
    ListNode newHead = reverseRecursive(head.next);
    head.next.next = head;   // next node points back to me
    head.next = null;        // sever the old forward link
    return newHead;
}

The two key lines are head.next.next = head and head.next = null. The first says "the node after me should now point at me"; the second cuts my original forward link so I don't create a cycle. It is still O(n) time, but each unresolved call sits on the stack, so it is O(n) space. For a long list this can overflow the stack — a real trade-off worth mentioning out loud.

Iterative vs Recursive: Complexity at a Glance

Both approaches reverse the list correctly. The difference is entirely about space and readability. The complexity numbers below are consistent across standard references such as GeeksforGeeks' reverse-a-linked-list guide.

ApproachTimeSpaceNotes
Iterative (3 pointers)O(n)O(1)Preferred answer; no stack risk; best for production
RecursiveO(n)O(n)Elegant, but call stack can overflow on long lists
Using an extra array/stackO(n)O(n)Works but wastes memory; usually a red flag in interviews

If an interviewer asks you to "reverse a linked list iteratively and recursively," lead with the iterative O(1)-space solution, then show the recursive one and explicitly name the stack cost as the reason you'd default to iterative in real code. For deeper background on why linked lists behave this way, MIT's 6.006 Introduction to Algorithms covers sequence and pointer-based data structures in its early lectures.

Common Mistakes and Interview Tips

The reverse-linked-list interview question is popular precisely because it exposes small pointer-handling errors. Watch for these:

  • Losing the rest of the list. Reassigning curr.next before saving it into a temp variable strands every following node. Always save next first.
  • Forgetting to return the new head. After reversal the original head is now the tail, and curr is null. Return prev, not head.
  • Not terminating the tail. In the recursive version, skipping head.next = null leaves a dangling forward link and can create a cycle.
  • Fumbling the base case. Handle empty (head is None) and single-node (head.next is None) lists explicitly so the recursion stops cleanly.

How to talk through it in an interview: state the plan before you code ("I'll use three pointers and flip each link in one pass"), narrate the four assignment lines as you write them, then trace a tiny example like 1 -> 2 -> 3 aloud to prove it. Finish by stating complexity unprompted — "O(n) time, O(1) space" — and mentioning the recursive alternative. That structure signals seniority as much as the correct code does.

To rehearse the surrounding fundamentals, start with our roundup of common coding interview questions. Then work through the broader software engineering interview questions guide. Data-focused candidates should also skim the data engineer interview questions list.

Next step

Use Articuler to act on what you just read

Start with one concrete goal: investor intros, sales prospects, event meetings, hiring-manager outreach, or expert conversations. Articuler turns that goal into people, prep, and messages.

Start networking with intent

FAQ

How do you reverse a linked list in O(1) space?

Use the iterative three-pointer method. Track prev, curr, and a temporary next. On each node, save next, point curr.next back to prev, then advance prev and curr. You never allocate memory proportional to the list length, so space stays constant at O(1) while time is O(n).

Is the iterative or recursive approach better for reversing a linked list?

For interviews and production, iterative is generally better: same O(n) time but O(1) space versus O(n) space for recursion. The recursive version is more elegant and worth showing to demonstrate range, but it risks a stack overflow on very long lists, so name that trade-off explicitly.

Why is "reverse a linked list" such a common interview question?

It is short enough to solve in a few minutes yet exposes real pointer-manipulation skill: saving references before overwriting them, handling edge cases, and returning the correct new head. Interviewers can quickly see whether you reason carefully about state, which is why it appears on nearly every coding-interview list.

What are the edge cases to handle when reversing a linked list?

An empty list (head is null) should return null, and a single-node list should return itself unchanged. Both your iterative loop and your recursive base case handle these through their natural termination conditions. Test them before you claim the solution is done.

From Whiteboard to Hiring Manager

Nailing "reverse a linked list" gets you past the technical screen — but that only matters if the right person is expecting your application. Reaching the hiring manager or a warm referral is what converts into an interview. That is where Articuler helps: its semantic matching searches across 980M+ profiles to surface the exact people at your target companies, and its Playbook turns those connections into a concrete outreach plan. Solve the algorithm to prove you can do the job; use Articuler to make sure the people who do the hiring know you exist.

Keep reading

More from Guides

Resources