#143 Reorder List
the problem
In plain words
Reorder L0 → L1 → … → Ln into L0 → Ln → L1 → Ln−1 → L2 → … in place. Only the links may change, not the values.
in head = [1,2,3,4]
out [1,4,2,3]
in head = [1,2,3,4,5]
out [1,5,2,4,3]
- 1 ≤ number of nodes ≤ 5·10⁴
- 1 ≤ Node.val ≤ 1000
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternFast & slow pointersIn-place linked-list rewiring
The answer alternates the front half with the reversed back half. So: find the middle, reverse the second half, then weave the two lists together — three moves you already know.
solutions
From brute force to optimal
Put nodes in an ArrayList to get O(1) access to the back, then link front/back alternately.
- Collect nodes.
- i = 0, j = n − 1: link i → j → i+1, move inward.
- Set the last node's next to null.
One pass to collect, one to relink.
The node array.
class Solution { public void reorderList(ListNode head) { List<ListNode> nodes = new ArrayList<>(); for (ListNode p = head; p != null; p = p.next) nodes.add(p); int i = 0, j = nodes.size() - 1; while (i < j) { nodes.get(i).next = nodes.get(j); // front → back i++; if (i == j) break; nodes.get(j).next = nodes.get(i); // back → next front j--; } if (!nodes.isEmpty()) nodes.get(i).next = null; // the meeting node is the new tail }}Find the end of the first half, reverse the second half, merge alternately.
- slow/fast with
fast.next != null && fast.next.next != null→ slow ends the first half. - second = reverse(slow.next); slow.next = null.
- Alternate: first → second → first.next → …
Three linear passes.
In-place rewiring.
class Solution { public void reorderList(ListNode head) { if (head == null || head.next == null) return; // 1. find the end of the first half ListNode slow = head, fast = head; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } // 2. reverse the second half and cut the list in two ListNode second = reverse(slow.next); slow.next = null; // 3. weave the halves together ListNode first = head; while (second != null) { ListNode n1 = first.next, n2 = second.next; first.next = second; second.next = n1; first = n1; second = n2; } } private ListNode reverse(ListNode head) { ListNode prev = null; while (head != null) { ListNode next = head.next; head.next = prev; prev = head; head = next; } return prev; }}Dry run
in the room
How to say it in the interview
talk track
- Name the three sub-steps before writing any code — interviewers grade the decomposition.
- Say why you cut with
slow.next = null: otherwise the first half still runs into the (now reversed) second half.
traps
- Forgetting
slow.next = null→ a cycle. - Losing
first.next/second.nextwhile weaving — save both before rewiring.
what they ask next
Follow-ups
Why not a stack of the back half?
It works (push the back half, pop while weaving) but costs O(n) space. Reversing in place gives the same back-to-front order for O(1).
before you submit
Edge cases to test
- One or two nodes → unchanged.
- Odd length: the middle node ends up last.
- Even length: the two middle nodes end up last.
practise next
Similar problems
- #234Palindrome Linked ListEasyin Linked Lists
- #876Middle of the Linked ListEasyin Linked Lists
- #206Reverse Linked ListEasyin Linked Lists