Topicsβ€ΊLinked Listβ€ΊReorder List (Half Reverse, Merge)
πŸ“–

Reorder List (Half Reverse, Merge)

Linked List
~20 min read
5 practice problems

Overview

Reorder list means rearranging the list so that nodes alternate between the first half and the second half in reverse order: L0 β†’ Ln β†’ L1 β†’ Lnβˆ’1 β†’ L2 β†’ … You do not create new nodes; only rewire pointers. The approach: (1) find the middle with Fast and Slow Pointers, (2) reverse the second half with Reverse In-Place, (3) merge the first half and the reversed second half alternately. All in O(n) time and O(1) space.

Key idea: After splitting at the middle and reversing the second half, you have two lists: [L0, L1, …] and [Ln, Lnβˆ’1, …]. Weave them one node at a time.


When to Use

  • Reorder list β€” Exact problem: L0 β†’ Ln β†’ L1 β†’ Lnβˆ’1 β†’ …
  • Any "interleave two halves" β€” Same pattern: find middle, reverse second half (or not, depending on desired order), merge.

How It Works

  1. Find middle: Fast/slow; when fast reaches the end, slow is at the last node of the first half. Set secondHead = slow.next, then slow.next = null to split.
  2. Reverse second half: Reverse the list starting at secondHead; get the new head of the reversed half.
  3. Merge: Two pointers: first at original head, second at the reversed second half head. While second is not null: save first.next and second.next, set first.next = second, second.next = saved first.next, advance first and second.

Example 1: Reorder List (In-Place)

Problem: You are given the head of a singly linked list. Reorder it to: L0 β†’ Ln β†’ L1 β†’ Lnβˆ’1 β†’ L2 β†’ … Do not return anything; modify the list in-place.

function reorderList(head: ListNode | null): void {
  if (head === null || head.next === null) return;
  let slow: ListNode | null = head;
  let fast: ListNode | null = head;
  while (fast?.next?.next !== null) {
    slow = slow!.next;
    fast = fast.next.next;
  }
  let second = reverseList(slow!.next);
  slow!.next = null;
  let first: ListNode | null = head;
  while (second !== null) {
    const next1 = first!.next;
    const next2 = second.next;
    first!.next = second;
    second.next = next1;
    first = next1;
    second = next2;
  }
}
function reverseList(head: ListNode | null): ListNode | null {
  let prev: ListNode | null = null;
  let curr: ListNode | null = head;
  while (curr !== null) {
    const next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return prev;
}
  • Time: O(n), Space: O(1).

Edge Cases

  • Empty or single node β€” Return immediately; nothing to reorder.
  • Two nodes β€” Middle is first node; second half has one node; merge gives L0 β†’ L1 β†’ null (already correct).
  • Odd length β€” First half has one more node; when second is exhausted, first.next is already the rest of the first half; no extra work.

Common Mistakes

  1. Not splitting β€” Set slow.next = null so the first half and second half are truly separate before reversing.
  2. Merge order β€” Attach second to first, then second.next to the old first.next; then advance first = next1, second = next2.
  3. Loop condition β€” Merge while (second !== null); when second is shorter (odd length), first may have one node left; that node is already in place.

Time and Space Complexity

  • Time: O(n) for find middle, reverse, and merge.
  • Space: O(1).

Summary