Reorder List (Leetcode #143)
You are given the head of a singly linked-list. The list can be represented as:
L0 → L1 → … → Ln - 1 → Ln
Reorder the list to be on the following form:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list's nodes. Only nodes themselves may be changed.
Example 1:
Input: head = [1,2,3,4]
Output: [1,4,2,3]
Example 2:
Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]
Constraints:
The number of nodes in the list is in the range
[1, 5 * 10<sup>4</sup>]
.1 <= Node.val <= 1000
Answer
There are multiple steps to solve this question. I will also be using linked list [1,2,3,4,5] as an example to solve this question.
The first step is to split the linked list into two halves:
# Split the list
slow = head
fast = head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
second = slow.next
slow.next = None
By using a fast and slow pointer we can split the list in half. This is a very common technique use to find the middle of the list.
The condition while fast and fast is use to find the middle of the list. This condition ensures that the loop terminates when the fast pointer cannot move two steps ahead, meaning it has either reached the end of the list or there is only one node left. This guarantees that the slow pointer will be at the correct middle position, especially for lists with an odd number of nodes.
second = slow.next
is used to capture the second half of the linked list while slow.next = None
us use to cut off the first half linked list.
now head = [1,2,3] and slow = [4,5]
The second step of the code is to reverse the order of the second halves:
# Reverse the second half of the list
prev = None
curr = second
while curr:
temp = curr.next
curr.next = prev
prev = curr
curr = temp
second = prev
I've already solved this in my previous article so I won't go into a lot of details but now we have
head = [1,2,3]
second = [5,4]
The final step is to merge the two lists:
# Merge the two halves
first = head
while second:
temp1, temp2 = first.next, second.next
first.next = second
second.next = temp1
first = temp1
second = temp2
Initial Lists:
first
(head) = [1, 2, 3]second
= [5, 4]
Step-by-Step Merging Process
Step 1:
Initial State:
first
= 1 -> 2 -> 3second
= 5 -> 4
Temp Variables:
temp1
=first.next
= 2 -> 3temp2
=second.next
= 4
Linking:
first.next
=second
=> 1 -> 5second.next
=temp1
=> 5 -> 2 -> 3
Move Pointers:
first
=temp1
= 2 -> 3second
=temp2
= 4
Current State:
- List: 1 -> 5 -> 2 -> 3
Step 2:
Initial State:
first
= 2 -> 3second
= 4
Temp Variables:
temp1
=first.next
= 3temp2
=second.next
= None
Linking:
first.next
=second
=> 2 -> 4second.next
=temp1
=> 4 -> 3
Move Pointers:
first
=temp1
= 3second
=temp2
= None
Current State:
- List: 1 -> 5 -> 2 -> 4 -> 3
Final State:
The
second
pointer is nowNone
, so the loop terminates.The reordered list is: 1 -> 5 -> 2 -> 4 -> 3