Reorder List
This problem is a combination of these three easy problems:
- Middle of the Linked List.
- Reverse Linked List.
- Merge Two Sorted Lists.
You can reorder a linked list as described by performing the following steps:
- Find the Middle of the List: Use the slow and fast pointer technique to find the middle of the list.
- Reverse the Second Half: Reverse the second half of the list.
- Merge the Two Halves: Merge the first half and the reversed second half alternately.
Here’s a Python function to accomplish this:
|
|
Explanation
- Step 1: Find the middle of the list using the slow and fast pointer method.
- Step 2: Reverse the second half of the list by changing the pointers.
- Step 3: Merge the original first half and the reversed second half by rearranging the pointers.
Key Takeaway
This approach reorders the linked list without modifying the values in the nodes, satisfying the constraints. By splitting, reversing, and merging, the list is reordered in-place as required.
=begin
Define the Terms
Define the Interface Input: head Output: nothing
Analyze the Input and Output
Initial State | What is the next state? | What is the state before the penultimate state? | What is the penultimate state? Final State
Remove existing constraints and think freely. Sometimes this simplifies the problem and you can make some progress.
What if we don’t have any constraints? Traversing from forward and backward and joining it.
Work backwards from the result.
- What is the step before the final state?
Identify the Invariants
Identify the constraints
Search the Problem Space
Classify the Problem
Analyze the Examples
Solve the Problem by Hand
[1,2,3,4]
[1,4] - First connects to the last [2,3] - Second connects to the element before last
[1,4] -> [2,3]
[1,2,3,4,5] [1,5] [2,4] [3]
[1,5] -> [2,4]
[1,5] -> [2,4] -> [3]
We split the list by half Reverse the second half [4, 3] [1,2] [4,3]
1 -> 4 -> 2 -> 3
If you have odd number of elements in the linked list the middle element will to the last.
[1,2,3,4,5] We need to split this list by half. Do we need to make the middle element part of the first list or the second list.
[1,2] [3,4,5] - Split [1,2] [5, 4, 3] - Reverse second half [1,5] [2, 4, 3] - 1 connects to 5, 2 connects to 4 [1, 5] -> [2,4,3] - Merge first list with the second list [1,5,2,4,3]
[1,2, 3] [4,5] - Split [1,2, 3] [5, 4] - Reverse second half [1,2,3] [5,4] - 1 connects to 5, 2 connects to 4 [1, 5, 3] -> [2,4] - Merge first list with the second list [1,5,3,2,4]
Describe the Pattern
Distill the Observations to Create Insights
Brute Force Approach
Analyze Time and Space Complexity
Time: O(N) Space: O(1)
Outline the Solution - Split the list by half - If you have odd number of elements, add the middle element to the first list - Reverse the second half - Alternate linking the elements in the both the linked lists.
Key Takeaways
Problem decomposition
v
1 -> 2 -> 3 -> 4 -> 5
^
=end
Definition for singly-linked list.
class ListNode
attr_accessor :val, :next
def initialize(val = 0, _next = nil)
@val = val
@next = _next
end
end
@param {ListNode} head
@return {Void} Do not return anything, modify head in-place instead.
def reorder_list(head) slow = head fast = head
while !fast.nil? && !fast.next.nil? slow = slow.next fast = fast.next.next end
previous = nil current = slow
while !current.nil?
save the link of the next node of the current
tmp = current.next
Reverse the link
current.next = previous
move follower and leader by one
previous = current
current = tmp
end
1 -> 2 4 -> 3
head, slow
first = head
???
second = previous
while !second.next.nil?
tmp = first.next
first.next = second
first = tmp
tmp = second.next
linking the end
second.next = first
second = tmp
end
end