Leetcode #143
getting the correct idea is intuitive, but knowing how to implement it is quite tricky, had to watch the neetcode video to learn the method of using the slow and fast pointers, for example. also got tripped up and forgot to break the link between the first and second half initially.
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.
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 * 104].
1 ⇐ Node.val ⇐ 1000
Optimal Solution: (Reverse + Merge)
# 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: ListNode | None) -> None:
"""
Do not return anything, modify head in-place instead.
- find the middle (new end)
- break into first half, second half
- reverse second half
- merge
"""
# slow moves by 1 node, fast by 2
slow, fast = head, head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
second = slow.next
# reverse second
## MUST BREAK LINK!
prev = slow.next = None
while second:
temp = second.next
second.next = prev
prev = second
second = temp
first,second = head,prev
while second:
temp1 = first.next
temp2 = second.next
first.next = second
second.next = temp1
first, second = temp1, temp2