The Problem

You are given the head of a singly linked list:

L0 โ†’ L1 โ†’ โ€ฆ โ†’ Ln-1 โ†’ Ln

Reorder the list to be in the following form:

L0 โ†’ Ln โ†’ L1 โ†’ Ln-1 โ†’ L2 โ†’ Ln-2 โ†’ โ€ฆ

You may not modify the values in the list's nodes. Only the nodes themselves may be changed. The reordering must be done in-place.

Interactive Visualization

Speed:
Linked List Visualization
Press Step or Play to begin
Code
fun reorderList(head: ListNode?) {    // Phase 1: Find middle    var slow = head; var fast = head?.next    while (fast != null && fast.next != null) {        slow = slow?.next        fast = fast.next?.next }    // Phase 2: Reverse second half    var second = slow?.next    slow?.next = null    var prev: ListNode? = null    while (second != null) {        val tmp = second.next        second.next = prev        prev = second        second = tmp }    // Phase 3: Merge two halves    var first = head; second = prev    while (second != null) {        val tmp1 = first?.next; val tmp2 = second.next        first?.next = second        second.next = tmp1        first = tmp1; second = tmp2 } }
Status
Press Step or Play to begin.

How It Works

Key Insight

This problem elegantly combines three classic linked list operations into one algorithm: finding the middle (slow/fast pointers), reversing a linked list, and merging two lists. By splitting the list, reversing the back half, and interleaving, we achieve the reorder in O(1) extra space without needing an array or stack.

The Algorithm

  • Phase 1 โ€” Find Middle: Use slow and fast pointers. slow starts at head, fast starts at head.next. Move slow by 1 and fast by 2 each step. When fast reaches the end, slow is at the middle node.
  • Phase 2 โ€” Reverse Second Half: Starting from slow.next, reverse the second half of the list in place using the standard three-pointer reversal (prev, curr, next). Disconnect the two halves by setting slow.next = None.
  • Phase 3 โ€” Interleave/Merge: Take one node from the first half, then one node from the reversed second half, alternating until all nodes are connected. This produces the desired L0 โ†’ Ln โ†’ L1 โ†’ Ln-1 โ†’ ... ordering.

Complexity

Time O(n)
Space O(1)

Each phase traverses the list (or half of it) once, giving O(n) total time. We only use a constant number of pointer variables โ€” no additional data structures are needed.