The problem
You get the head of a singly linked list L0 -> L1 -> … -> Ln. Rearrange it in place into L0 -> Ln -> L1 -> Ln-1 -> L2 -> …. You must relink the nodes, not just swap their values.
Input: 1 -> 2 -> 3 -> 4 -> 5
Output: 1 -> 5 -> 2 -> 4 -> 3Take from the front, then the back, then the front again, until you meet in the middle.
How to think about it
Start with brute force. Copy the nodes into an array. Then use two indices, one from each end, and relink arr[i] -> arr[j] -> arr[i+1] -> …. That is O(n) time and O(n) space. It’s a solid first answer, and the follow-up is to do it in O(1) space.
Look at the output shape. The result alternates between the front half in order and the back half in reverse. With 1 2 3 4 5, the front half is 1 2 3, the back half reversed is 5 4, and weaving them gives 1 5 2 4 3.
The key insight: this is three small problems glued together. (1) Find the middle with fast and slow pointers. (2) Cut the list there and reverse the back half in place. (3) Merge the two lists by alternating nodes. Each piece is a standard linked-list move in O(n) time and O(1) space, so the whole thing is too.
Which pattern is this? Fast & slow pointers to split, then in-place reversal and merging. The tell is “the answer pairs the front of a list with its back”.
Approach
- If the list is empty, return.
- Move
sone step andftwo steps whilef.nextandf.next.nextexist.sstops at the end of the front half (the first middle). - Set
second = s.next, then cut the list withs.next = None. - Reverse
secondin place;prevbecomes its new head. - Weave: with
firston the front half andsecondon the reversed back half, linkfirst -> second -> (old first.next), advance both, and repeat whilesecondhas nodes.
Solution
def reorder_list(head):
if not head: return None
s = f = head
while f.next and f.next.next: s = s.next; f = f.next.next # s = end of front half
second = s.next; s.next = None; prev = None # cut into two lists
while second: second.next, prev, second = prev, second, second.next # reverse back half
first = head; second = prev
while second: # weave front and back
first.next, first = second, first.next
second.next, second = first, second.next
return head
# reorder_list([1,2,3,4,5]) -> [1,5,2,4,3]Dry run
On 1 -> 2 -> 3 -> 4 -> 5:
| Phase | State |
|---|---|
| find middle | s stops on node 3 |
| cut | front half 1 2 3, back half 4 5 |
| reverse back half | 5 4 |
| weave 1 | 1 5 2 3 |
| weave 2 | 1 5 2 4 3 |
| end | second is None; result 1 5 2 4 3 |
On the even list 1 2 3 4, the middle is node 2, the halves are 1 2 and 4 3, and the weave gives 1 4 2 3.
Complexity
- Time: O(n). Finding the middle, reversing half the list and weaving are each one linear pass.
- Space: O(1). Only pointer variables; no nodes are created.
Edge cases and pitfalls
- Empty list: returns immediately.
- One or two nodes: the front half holds everything (or the back half is one node), and the list comes out unchanged. On
1the result is1. - Forgetting to cut (
s.next = None) leaves the front half still linked into the back half, which creates a cycle after weaving. - First vs second middle. This loop stops on the first middle, so the front half is never shorter than the back half. That’s why the weave can loop on
secondalone. - Swapping values instead of nodes is not allowed by the problem, and interviewers will notice.
Related problems
- Palindrome Linked List (LeetCode 234): the same middle-and-reverse set-up, then a comparison.
- Reverse Linked List (LeetCode 206): the reversal step on its own.
- Merge Two Sorted Lists (LeetCode 21): merging two lists, chosen by value instead of alternating.
- 1.Middle of the Linked List (LeetCode 876)
- 2.Linked List Cycle (LeetCode 141)
- 3.Happy Number (LeetCode 202)
- 4.Palindrome Linked List (LeetCode 234)
- 5.Intersection of Two Linked Lists (LeetCode 160)
- 6.Linked List Cycle II (LeetCode 142)
- 7.Find the Duplicate Number (LeetCode 287)
- 8.Remove Nth Node From End of List (LeetCode 19)
- 9.Reorder List (LeetCode 143)
- 10.Circular Array Loop (LeetCode 457)