143. Reorder List
Quick Identifier
- Topic: linked-list
- Pattern: In-place Linked List Reversal + merge
- Difficulty: Medium
- Companies: Facebook, Amazon, Google, Microsoft, Oracle
- Frequency: High
- LeetCode: 143
Quick Sights
- Time Complexity:
O(n)from the optimal approach. - Space Complexity:
O(1)from the optimal approach. - Core Mechanism: Given a singly linked list, reorder nodes to
L0 -> Ln -> L1 -> Ln-1 -> ...in place without extraO(n)space for new nodes (only pointer churn).
Concept Explanation
Given a singly linked list, reorder nodes to L0 -> Ln -> L1 -> Ln-1 -> ... in place without extra O(n) space for new nodes (only pointer churn).
The key is to state the invariant before coding: what part of the input is already settled, what state is still unresolved, and what single operation makes progress without losing correctness.
Recognition cues:
- “Interleave first and last” on a list
- Three steps: find middle, reverse second half, merge two lists
- Linear time,
O(1)extra
Study Pattern (SDE3+)
- 0-3 min: restate I/O and brittle edges aloud, then verbalize two approaches with time/space before you touch the keyboard.
- Implementation pass: one-line invariant above the tight loop; state what progress you make each iteration.
- 5 min extension: pick one constraint twist (immutable input, stream, bounded memory, parallel readers) and explain what in your solution breaks without a refactor.
Diagram
This diagram shows the algorithm movement for this problem family.
Loading diagram…
Approaches
- Brute force —
O(n)time /O(n)space — copy to array, rewrite indices. - Better — two passes with stack for second half —
O(n)space. - Optimal —
O(n)time /O(1)space — slow/fast for mid, reverse tail, merge like two sorted lists but always take from alternating heads.
Optimal Solution
Go
type ListNode struct {
Val int
Next *ListNode
}
func reorderList(head *ListNode) {
if head == nil || head.Next == nil {
return
}
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
second := slow.Next
slow.Next = nil
second = reverseList(second)
mergeInterleave(head, second)
}
func reverseList(head *ListNode) *ListNode {
var previous *ListNode
current := head
for current != nil {
next := current.Next
current.Next = previous
previous = current
current = next
}
return previous
}
func mergeInterleave(first *ListNode, second *ListNode) {
for second != nil {
nextFirst := first.Next
nextSecond := second.Next
first.Next = second
second.Next = nextFirst
first = nextFirst
second = nextSecond
}
}JavaScript
class ListNode {
constructor(val = 0, next = null) {
this.val = val;
this.next = next;
}
}
function reorderList(head) {
if (head === null || head.next === null) {
return;
}
let slow = head;
let fast = head;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
let second = slow.next;
slow.next = null;
second = reverseList(second);
mergeInterleave(head, second);
}
function reverseList(head) {
let previous = null;
let current = head;
while (current !== null) {
const next = current.next;
current.next = previous;
previous = current;
current = next;
}
return previous;
}
function mergeInterleave(first, second) {
while (second !== null) {
const nextFirst = first.next;
const nextSecond = second.next;
first.next = second;
second.next = nextFirst;
first = nextFirst;
second = nextSecond;
}
}Walkthrough
1 -> 2 -> 3 -> 4
| phase | result |
|---|---|
| mid split | 1->2 and 4->3 (reversed) |
| merge | 1->4->2->3 |
Invariant: first half length equals or exceeds second; merge always has a node from first to splice after.
Edge Cases
- Length 1 or 2 — no visible change or single swap path still works.
- Odd length — middle element naturally ends at tail after merge.
Pitfalls
- Forgetting to cut list at
slow.Next = nil— creates cycles. - Reversing full list instead of second half only.
Similar Problems
- 206. Reverse Linked List — reverses second segment.
- 234. Palindrome Linked List — also splits mid + reverse half.
- 21. Merge Two Sorted Lists — merge discipline without key comparison.
Variants
k-way interleave — extend merge round-robin.- Array input — same pointer story after building list.
Mind-Map Tags
#linked-list #split-list #reverse-half #interleave-merge
Mark this page when you finish learning it.
Last updated on
Spotted something unclear or wrong on this page?