Reorder a Linked List

Solve this Problem
Medium20–25 min
Topics
Companies
Practice:GFG ↗
Given the head of a singly linked list L0 → L1 → ... → Ln-1 → Ln, reorder it in place into L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → ..., without changing any node's value. The optimal solution turns this into a problem it already knows how to solve twice over: find the middle and split the list into two halves, reverse the second half (the same relink primitive used to reverse any run of nodes), and then merge the two halves — one running forward from the front, one running "backward" from the end — by strictly alternating a node from each side. That alternation is exactly what produces the L0, Ln, L1, Ln-1, ... pattern, with every step just re-linking existing nodes.

Test Case 1:

Input:head = [1, 2, 3, 4]
Output:[1, 4, 2, 3]
Explanation:L0, Ln, L1, Ln-1 — front and back nodes alternate inward.

Test Case 2:

Input:head = [1, 2, 3, 4, 5]
Output:[1, 5, 2, 4, 3]
Explanation:The middle node (3) ends up last since there's no partner left to pair it with.

Test Case 3:

Input:head = [1]
Output:[1]
Explanation:A single node has nothing to reorder.

Constraints

  • 1 ≤ number of nodes in head ≤ 200
  • -1000 ≤ node value ≤ 1000
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

🧪Try your own test case
1class Solution {
2 public Node reorderList(Node head) {
3 if (head == null || head.next == null) {
4 return head;
5 }
6 Node slow = head, fast = head;
7 while (fast.next != null && fast.next.next != null) {
8 slow = slow.next;
9 fast = fast.next.next;
10 }
11 Node secondHead = slow.next;
12 slow.next = null;
13 Node prev = null;
14 Node curr = secondHead;
15 while (curr != null) {
16 Node nextNode = curr.next;
17 curr.next = prev;
18 prev = curr;
19 curr = nextNode;
20 }
21 secondHead = prev;
22 Node first = head;
23 Node second = secondHead;
24 while (second != null) {
25 Node firstNext = first.next;
26 Node secondNext = second.next;
27 first.next = second;
28 if (firstNext != null) {
29 second.next = firstNext;
30 }
31 first = firstNext;
32 second = secondNext;
33 }
34 return head;
35 }
36}
37
1
2
3
4
5
null
Variables
head1
COMPARE

More than one node — reordering actually needs to happen.

Step 1 / 43

Approach & Solutions

Brute Force — Collect Nodes Into an Array, Reorder by Index

Good

Copy every value into an array, then build the reordered sequence by alternately taking from the front and the back of that array. Walk the list once more overwriting .val in that new order. Simple and correct, but it costs an array (twice over, really) the size of the whole list — the optimal solution reorders in place with no extra memory.

TimeO(n)
SpaceO(n)
1// Node definition used in this problem: 2// class Node { 3// int val; 4// Node next; 5// } 6 7class Solution { 8 public Node reorderList(Node head) { 9 List<Integer> vals = new ArrayList<>(); 10 Node curr = head; 11 while (curr != null) { 12 vals.add(curr.val); 13 curr = curr.next; 14 } 15 List<Integer> reordered = new ArrayList<>(); 16 int lo = 0, hi = vals.size() - 1; 17 while (lo <= hi) { 18 reordered.add(vals.get(lo)); 19 lo++; 20 if (lo <= hi) { 21 reordered.add(vals.get(hi)); 22 hi--; 23 } 24 } 25 curr = head; 26 for (int v : reordered) { 27 curr.val = v; 28 curr = curr.next; 29 } 30 return head; 31 } 32}

Optimal — Split, Reverse the Second Half, Merge Alternately

Optimal

Find the end of the first half with slow/fast pointers, then cut the list into two independent halves right there. Reverse the second half in place — the exact same relink primitive used to reverse any run of nodes. What's left is two ordinary lists of (almost) equal length, one running forward from the original front and one running "backward" from the original end. Merge them by strictly alternating one node from each — first, second, first, second — which produces L0, Ln, L1, Ln-1, ... automatically, with no new nodes.

TimeO(n)
SpaceO(1)
1// Node definition used in this problem: 2// class Node { 3// int val; 4// Node next; 5// } 6 7class Solution { 8 public Node reorderList(Node head) { 9 if (head == null || head.next == null) { 10 return head; 11 } 12 Node slow = head, fast = head; 13 while (fast.next != null && fast.next.next != null) { 14 slow = slow.next; 15 fast = fast.next.next; 16 } 17 Node secondHead = slow.next; 18 slow.next = null; 19 Node prev = null; 20 Node curr = secondHead; 21 while (curr != null) { 22 Node nextNode = curr.next; 23 curr.next = prev; 24 prev = curr; 25 curr = nextNode; 26 } 27 secondHead = prev; 28 Node first = head; 29 Node second = secondHead; 30 while (second != null) { 31 Node firstNext = first.next; 32 Node secondNext = second.next; 33 first.next = second; 34 if (firstNext != null) { 35 second.next = firstNext; 36 } 37 first = firstNext; 38 second = secondNext; 39 } 40 return head; 41 } 42}

Related Problems