143. Reorder List
url: https://leetcode.com/problems/reorder-list/description/
Input: head = [1,2,3,4,5,6]
Output: [1,6,2,5,3,4]
1 2 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null => 1 -> 6 -> 2 -> 5 -> 3 -> 4 -> null
📝 Solution
Approach
To solve the problem 143. Reorder List, we need to identify a pattern that simplifies the solution.
In essence, we need to reorder the list by alternately placing the first and last elements until we reach the middle.
Strategy:
- Find the middle and split the LL
- To reorder the list, we first need to find the middle to divide it into two separate parts. The challenge here is finding the middle node efficiently in a singly linked list. A brute-force approach would involve iterating through all nodes to count them, then traversing again from the head to reach the middle, but this is inefficient.
Using the fast & slow pointer algorithm, allows us to locate the middle in a single pass.This approach not only finds the middle efficiently but is also commonly used to detect cycles in a linked list. (a.k.a 🐰 & 🐢)
1 2 3 4 5 6
# set pointers at the start line fast = slow = head # edge case: odd or even length? while fast and fast.next: slow = slow.next fast = fast.next.next
We need to check if the linked list length is odd or even. This is why we use
fastandfast.nextin the while condition. - To reorder the list, we first need to find the middle to divide it into two separate parts. The challenge here is finding the middle node efficiently in a singly linked list. A brute-force approach would involve iterating through all nodes to count them, then traversing again from the head to reach the middle, but this is inefficient.
- Reverse the rear LL
- By creating
nullnode at the beggining, we can reverse the direction.1 2 3 4
null 4 -> 5 -> 6 -> null null <- 4 5 -> 6 -> null null <- 4 <- 5 6 -> null null <- 4 <- 5 <- 6 null
To implement this logic, we use three pointers:
prev: Points to the previous node, starting fromnull.curr: Points to the current node that we want to redirect.temp: pointing he next node ofcurrto proceed with the next redirecting1 2 3 4 5 6 7
prev = None curr = slow # `slow` is the middle from step 1 while curr: temp = curr.next curr.next = prev prev = curr curr = temp
- By creating
- Merge LLs
- At the beginning of this stage, we have two linked lists., so we need to merge them into a single LL.
1 2 3 4 5 6
1 -> 2 -> 3 -> null 6 -> 5 -> 4 -> null => 1 -> 6 -> 2 -> 5 -> 3 -> 4 -> null
1 2 3 4 5
first = head second = prev #prev stopped at the last element from step 2 while second.next: first.next, first = second, first.next second.next, second = first, second.next
- At the beginning of this stage, we have two linked lists., so we need to merge them into a single LL.
💻 Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution:
def reorderList(self, head: Optional[ListNode]) -> None:
# set pointers at the start line
fast = slow = head
# edge case: odd or even length?
while fast and fast.next:
slow = slow.next
fast = fast.next.next
prev = None
curr = slow # slow is the middle from step 1
while curr:
temp = curr.next
curr.next = prev
prev = curr
curr = temp
first = head
second = prev #`prev` stopped at the last element from step 2
while second.next:
first.next, first = second, first.next
second.next, second = first, second.next
This post is licensed under CC BY 4.0 by the author.