143. Reorder List

Overview
We need to reorder the listed list by inserting the reversed right half between the left half.
From: 1 -> 2 -> 3 -> ... -> n - 2 -> n - 1 -> n
To: 1 -> n -> 2 -> n - 1 -> 3 -> n -2 ...
Solution 1: Stack
Thinking
We can use a stack to save all the nodes,
and insert the popped-out nodes in between each node until reaching the middle of the stack.
Algorithm
-
Initialize an empty stack.
-
Iterate through the linked list and append each node into the stack.
-
Iterate through the range of the middle.
- Save the next node for relinking.
- Create a new node with the popped node from the stack.
- Link the new node to the saved next node.
- Relink the current node to the new node.
- Update the current node to the saved next node for next iteration.
-
Set the current node to None to remove the origin right-hand side of the linked list.
Implement
class Solution: def reorderList(self, head: Optional[ListNode]) -> None: """ Do not return anything, modify head in-place instead. """ stack: list[int] = [] current = head while current is not None: stack.append(current) current = current.next current = head middle = len(stack) // 2 for _ in range(middle): next = current.next new_node = stack.pop() new_node.next = next current.next = new_node current = next current.next = None
Complexity Analysis
Time complexity: O(n)
Iterating through the linked list to save the nodes to stack takes O(n).
Iterating through the the range of middle takes O(n/2).
The total complexity can be simplifies to O(n).
Space complexity: O(n)
We use an additional stack to save all the nodes of linked list, which takes O(n) space.