Problem
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.
Intuition
The problem involves reordering a singly linked list in a specific pattern. The approach is to break the linked list into two halves, reverse the second half, and then merge the two halves in the required order.
Approach
Use two pointers, slow and fast, to find the middle of the linked list. Move slow one step at a time and fast two steps at a time. When fast reaches the end, slow will be at the middle.
Set second to the node next to slow (which is the start of the second half).
Break the linked list into two halves by setting slow.next to None.
Reverse the second half of the linked list.
Merge the first and reversed second halves by alternating their nodes.
The final reordered linked list is obtained.
Complexity
- Time complexity:
The time complexity is O(n), where n is the number of nodes in the linked list. The algorithm iterates through the linked list twice: once to find the middle and once to reverse the second half.
- Space complexity:
The space complexity is O(1) since the solution uses only a constant amount of extra space for pointers.
Code
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reorderList(self, head: Optional[ListNode]) -> None:
slow , fast = head , head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
second = slow.next
slow.next = prev = None
while second:
nxt = second.next
second.next = prev
prev = second
second = nxt
first , second = head , prev
while second:
temp1 , temp2 = first.next , second.next
first.next = second
second.next = temp1
first , second = temp1 , temp2