Home › Blog › Linked List Reversal Pattern

In-Place Reversal of a Linked List: Template and Problems

The three-pointer template, how to reverse a sublist or k-sized groups, and the bugs that break it, with Python code we ran and tested.

The in-place reversal of a linked list pattern flips the next pointers of a list (or part of it) one node at a time using three pointers, prev, curr and next, so it runs in O(n) time and O(1) extra space. Reach for it whenever a problem asks you to reverse a list, a sublist between two positions, or every group of k nodes, or to compare or merge the two halves of a list without copying it into an array.

This guide gives you one template, three worked problems (LeetCode 92, 25 and 234, after the 206 template), the edge cases interviewers test, and a practice list. Every code block on this page was run in Python with asserts against a brute-force check before we published it.

When to use the reverse linked list pattern

The signal is almost always in the problem statement. Look for these:

If the problem instead asks you to find a cycle or the middle node, that is the fast and slow pointers pattern. Many medium problems combine the two: find the middle with fast and slow pointers, then reverse the second half in place.

How the in-place reversal of a linked list works

Picture 1 → 2 → 3 → None. You walk the list once. At each node you do four things in a fixed order: save the rest of the list, point the current node backward, then move both pointers one step forward.

StepprevcurrLinks after the step
StartNone11 → 2 → 3
After node 112None ← 1, and 2 → 3 still waiting
After node 223None ← 1 ← 2, and 3 still waiting
After node 33NoneNone ← 1 ← 2 ← 3

When curr becomes None, prev points at the old tail, which is the new head. That is why the function returns prev, not curr or the original head.

The Python template

This is the template to memorize. It is also the full solution to Reverse Linked List (LeetCode 206).

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def reverse_list(head):
    prev, curr = None, head
    while curr:
        nxt = curr.next      # 1. save the rest of the list
        curr.next = prev     # 2. flip this node's pointer
        prev = curr          # 3. move prev forward
        curr = nxt           # 4. move curr forward
    return prev              # prev is the new head

The order of the four lines matters. If you write curr.next = prev before saving curr.next, you lose the rest of the list. Say the order out loud in the interview: "save, flip, advance, advance."

The recursive version

Interviewers sometimes ask for recursion as a follow-up. It is shorter but uses O(n) call-stack space, so it is not O(1) extra space, and on a very long list it can hit CPython's default recursion limit of 1000 frames (check yours with sys.getrecursionlimit()).

def reverse_list_recursive(head):
    if head is None or head.next is None:
        return head
    new_head = reverse_list_recursive(head.next)
    head.next.next = head    # the node after head now points back to head
    head.next = None         # head becomes the tail
    return new_head

Worked problem 1: Reverse Linked List II (LeetCode 92)

Reverse Linked List II (LeetCode 92) asks you to reverse only the nodes from position left to position right (1-indexed) in one pass.

The idea: walk to the node just before position left (call it before). Then, right - left times, take the node right after the sublist's current tail and move it to the front of the sublist. A dummy node in front of head handles left = 1 without a special case.

def reverse_between(head, left, right):
    dummy = ListNode(0, head)
    before = dummy
    for _ in range(left - 1):        # stop at the node before position left
        before = before.next
    curr = before.next               # first node of the sublist; ends up as its tail
    for _ in range(right - left):
        moved = curr.next            # take the next node...
        curr.next = moved.next
        moved.next = before.next     # ...and insert it at the front of the sublist
        before.next = moved
    return dummy.next

Complexity: O(n) time in one pass, O(1) extra space. The "insert at the front" trick avoids having to reconnect both ends after a separate reversal, which is where most bugs on this problem come from.

Worked problem 2: Reverse Nodes in k-Group (LeetCode 25)

Reverse Nodes in k-Group (LeetCode 25) is the hard version: reverse every consecutive group of k nodes, and leave a final group with fewer than k nodes as it is.

The idea: keep a pointer group_prev to the node before the current group. First check that k nodes exist by finding the k-th node. Then run the standard reversal on the group, with one change: start prev at the node after the group, so the reversed group's tail is already linked to the rest of the list. Finally, hook group_prev to the new group head and move group_prev to the old first node, which is now the group's tail.

def reverse_k_group(head, k):
    dummy = ListNode(0, head)
    group_prev = dummy
    while True:
        kth = group_prev
        for _ in range(k):               # find the k-th node of this group
            kth = kth.next
            if kth is None:
                return dummy.next        # fewer than k nodes left: leave them as is
        group_next = kth.next
        prev, curr = group_next, group_prev.next
        while curr is not group_next:    # standard reversal, but the tail links to group_next
            nxt = curr.next
            curr.next = prev
            prev = curr
            curr = nxt
        first = group_prev.next          # old first node, now the group's tail
        group_prev.next = kth            # connect the previous part to the new group head
        group_prev = first

Complexity: O(n) time, since each node is visited a constant number of times (once to count the group, once to reverse it), and O(1) extra space. A recursive solution is common too, but it uses O(n/k) stack space.

Worked problem 3: Palindrome Linked List (LeetCode 234)

This one combines two patterns and is a favorite "can you do it in O(1) space?" follow-up. The array solution (copy values, compare with the reversed copy) is O(n) space. The in-place answer reuses reverse_list from the template:

  1. Find the middle with fast and slow pointers.
  2. Reverse the second half in place with the template.
  3. Compare the first half and the reversed second half node by node.
  4. Reverse the second half again so the caller gets the list back unchanged.
def is_palindrome(head):
    slow = fast = head
    while fast and fast.next:            # slow stops at the middle
        slow = slow.next
        fast = fast.next.next
    second = reverse_list(slow)          # reverse the second half in place
    a, b, ok = head, second, True
    while b:
        if a.val != b.val:
            ok = False
            break
        a, b = a.next, b.next
    reverse_list(second)                 # restore the input list
    return ok

Complexity: O(n) time, O(1) extra space. Step 4 is optional on LeetCode, but mentioning it in an interview shows you think about side effects on input you do not own.

Complexity of linked list reversal problems

ProblemApproachTimeExtra space
Reverse Linked List (206)Iterative three pointersO(n)O(1)
Reverse Linked List (206)RecursiveO(n)O(n) call stack
Reverse Linked List II (92)Dummy node + front insertionO(n)O(1)
Reverse Nodes in k-Group (25)Count k, reverse group, reconnectO(n)O(1)
Palindrome Linked List (234)Middle + reverse second halfO(n)O(1)
Any of the aboveCopy values into an arrayO(n)O(n), usually not accepted as the final answer

To see how O(1) and O(n) extra memory diverge as inputs grow, try the free Big-O complexity visualizer.

Common bugs and edge cases

Tip: Draw three boxes labeled prev, curr and next on your whiteboard or in a comment, and update them for the first two nodes before you code. Interviewers read that as clear thinking, and it catches pointer-order mistakes early.

Practice list: 8 linked list reversal problems

Do them in this order. Four are covered above; the rest reuse the same template with a twist.

#ProblemDifficultyTwist
206Reverse Linked ListEasyThe template itself
234Palindrome Linked ListEasyMiddle + reverse second half
92Reverse Linked List IIMediumReverse a sublist in one pass
24Swap Nodes in PairsMediumk-group reversal with k = 2
143Reorder ListMediumMiddle, reverse second half, then merge alternately
2130Maximum Twin Sum of a Linked ListMediumReverse second half, walk both halves together
445Add Two Numbers IIMediumReverse both inputs, add, reverse the result (or use stacks)
25Reverse Nodes in k-GroupHardCount, reverse, reconnect each group

Problem numbers and difficulty labels were checked on LeetCode as of October 2026. For where linked lists sit among the other core patterns, see 15 LeetCode patterns for coding interviews and the free coding interview cheat sheet.

How to practice this pattern out loud

Pointer problems go wrong under pressure, not at your desk. Practice explaining the "save, flip, advance" order while you type. In CoPilot Interview's Mock Interview you can include coding questions in your language; it reads each question aloud, scores your spoken answer out of 10 with what to fix and a model answer, and coding questions never auto-submit, so you can think in silence. The browser version at /ai-mock-interview has 113 real questions across 9 tracks, including coding, with nothing to install.

Related patterns to study next: two pointers, sliding window and merge intervals.

Practice linked list questions out loud

Run a free AI mock interview in your browser: answer a coding question, explain your approach, and get feedback on what to tighten.

Try a free AI mock interview

FAQ

What is the in-place reversal of a linked list pattern?

It is a technique that reverses all or part of a singly linked list by flipping each node's next pointer while walking the list once with three pointers (prev, curr and next). It runs in O(n) time and O(1) extra space because no new nodes or arrays are created.

How do you reverse a linked list in place in Python?

Set prev to None and curr to head. While curr is not None: save nxt = curr.next, set curr.next = prev, then move prev = curr and curr = nxt. When the loop ends, prev is the new head, so return prev.

Is the recursive reversal O(1) space?

No. Each recursive call adds a stack frame, so recursion uses O(n) extra space. On long lists it can also hit CPython's default recursion limit of 1000. Use the iterative version when the problem asks for O(1) space.

Why do linked list reversal solutions use a dummy node?

A dummy node placed before the head means the node before the reversed section always exists, even when the reversal starts at the first node. It removes special cases for position 1 and makes returning the new head simple: return dummy.next.

What is the time complexity of Reverse Nodes in k-Group?

O(n) time and O(1) extra space for the iterative solution. Each node is touched a constant number of times: once while counting the group and once while reversing it. A recursive solution is also O(n) time but uses O(n/k) stack space.

Which LeetCode problems use the reverse linked list pattern?

The core ones are Reverse Linked List (206), Reverse Linked List II (92) and Reverse Nodes in k-Group (25). It also appears inside Palindrome Linked List (234), Reorder List (143), Maximum Twin Sum of a Linked List (2130), Swap Nodes in Pairs (24) and Add Two Numbers II (445).