Given the head of a singly linked list LโโLโโโฆโLโโโโLโ, reorder it to LโโLโโLโโLโโโโLโโLโโโโโฆ. You may not modify node values โ only change the node links.
โข 1 โค number of nodes โค 5 ร 10โดโข 1 โค Node.val โค 1000
02
Section Two ยท Approach 1
Array + Rebuild โ O(n) space
Store all nodes in an array. Use two pointers (front and back) to relink in the desired order. Correct but O(n) extra space.
Problem: O(n) space for the array. We can achieve O(1) space by combining three linked-list primitives: find-middle, reverse, and merge.
03
Section Three ยท Approach 2
Three-Step In-Place โ O(n) time, O(1) space
The reordered list interleaves the first half with the reversed second half. Three steps: (1) find the middle, (2) reverse the second half, (3) merge alternating.
๐ก Mental model: Take a deck of cards 1-2-3-4-5. Split it at the middle: [1,2,3] and [4,5]. Reverse the second pile: [5,4]. Now interleave: take from first, then second โ 1,5,2,4,3. That's the reordered list.
Algorithm
Step 1 โ Find middle: Use slow/fast pointers. When fast reaches the end, slow is at the middle.
Step 2 โ Reverse second half: Reverse the list starting from slow.next. Cut the first half by setting slow.next = null.
Step 3 โ Merge alternating: Take one node from the first half, then one from the reversed second half, alternating.
๐ฏ Three classic sub-problems combined:
This problem is a composition of LC 876 (Middle of Linked List), LC 206 (Reverse Linked List), and LC 21 (Merge Two Sorted Lists) โ but with alternating instead of sorted merge.
Master each primitive first.
04
Section Four ยท Trace
Visual Walkthrough
Trace: 1 โ 2 โ 3 โ 4 โ 5:
Three-step reorder โ split, reverse, merge
05
Section Five ยท Implementation
Code โ Java & Python
Java โ Three-step in-place
classSolution {
publicvoidreorderList(ListNode head) {
if (head == null || head.next == null) return;
// Step 1: Find middleListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// Step 2: Reverse second halfListNode second = slow.next;
slow.next = null; // cut first halfListNode prev = null;
while (second != null) {
ListNode next = second.next;
second.next = prev;
prev = second;
second = next;
}
second = prev; // new head of reversed half// Step 3: Merge alternatingListNode first = head;
while (second != null) {
ListNode tmp1 = first.next, tmp2 = second.next;
first.next = second;
second.next = tmp1;
first = tmp1;
second = tmp2;
}
}
}
Python โ Three-step in-place
classSolution:
defreorderList(self, head: Optional[ListNode]) -> None:
if not head or not head.next: return# Step 1: Find middle
slow = fast = head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
# Step 2: Reverse second half
second = slow.next
slow.next = None
prev = Nonewhile second:
second.next, prev, second = prev, second, second.next
second = prev
# Step 3: Merge alternating
first = head
while second:
tmp1, tmp2 = first.next, second.next
first.next = second
second.next = tmp1
first, second = tmp1, tmp2
06
Section Six ยท Analysis
Complexity Analysis
Approach
Time
Space
Trade-off
Array + Rebuild
O(n)
O(n)
Simple but extra memory
Three-step โ optimal
O(n)
O(1)
Find middle + reverse + merge
07
Section Seven ยท Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
Single/two nodes
1 or 1โ2
Already in correct order โ nothing to do.
Even length
1โ2โ3โ4
Split: [1,2] and [4,3]. Merge: 1โ4โ2โ3.
Odd length
1โ2โ3โ4โ5
First half has extra node. Merge leaves middle node (3) at end.
โ Common Mistake: Not cutting the first half (forgetting slow.next = null). Without the cut, the merge step creates a cycle โ nodes from the first half still point forward into the reversed second half.