Reorder Linked List in DSA Python - Time & Space Complexity
We want to understand how the time needed to reorder a linked list changes as the list gets bigger.
Specifically, how the steps grow when we rearrange nodes from start and end alternately.
Analyze the time complexity of the following code snippet.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reorderList(head):
if not head or not head.next:
return
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
prev, curr = None, slow.next
slow.next = None
while curr:
next_temp = curr.next
curr.next = prev
prev = curr
curr = next_temp
first, second = head, prev
while second:
tmp1, tmp2 = first.next, second.next
first.next = second
second.next = tmp1
first, second = tmp1, tmp2
This code reorders a linked list by first finding the middle, reversing the second half, then merging both halves alternately.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Traversing the linked list multiple times using loops.
- How many times: Three main loops: one to find the middle, one to reverse the second half, and one to merge the two halves.
Each loop goes through about half or all of the list nodes, so the total steps grow roughly in a straight line with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 30 steps (3 passes of ~10 nodes) |
| 100 | About 300 steps |
| 1000 | About 3000 steps |
Pattern observation: The operations increase linearly as the list size grows.
Time Complexity: O(n)
This means the time to reorder grows directly in proportion to the number of nodes in the list.
[X] Wrong: "Reversing the second half or merging halves takes extra nested loops, so complexity is O(n²)."
[OK] Correct: Each loop runs separately over parts of the list without nesting inside each other, so total steps add up linearly, not multiply.
Understanding this helps you explain how to efficiently reorder linked lists, a common task in coding challenges and real-world data handling.
"What if we used recursion to reverse the second half instead of a loop? How would the time complexity change?"
Practice
Reorder Linked List problem?Solution
Step 1: Understand the problem statement
The problem asks to reorder the list so that nodes come alternately from the start and end, like L0 -> Ln -> L1 -> Ln-1 -> L2 -> Ln-2 ...Step 2: Differentiate from other operations
This is not sorting or reversing the entire list, but a specific pattern of rearrangement.Final Answer:
Rearrange the list so nodes alternate from start and end towards the center -> Option DQuick Check:
Reorder means alternate start/end nodes = A [OK]
- Confusing reorder with sorting
- Thinking reorder means full reversal
- Assuming duplicates are removed
Solution
Step 1: Understand slow and fast pointer technique
Using slow and fast pointers starting at head, fast moves twice as fast to find middle.Step 2: Check code correctness
slow, fast = head, head while fast and fast.next: slow = slow.next fast = fast.next.next second = slow.next slow.next = null correctly initializes both at head and uses while fast and fast.next to move pointers safely.Final Answer:
Option B code snippet correctly splits the list into two halves -> Option BQuick Check:
Slow and fast start at head, fast moves twice = B [OK]
- Starting fast at head.next causes off-by-one errors
- Incorrect while loop conditions causing crashes
- Not breaking the list by setting slow.next = null
1 -> 2 -> 3 -> 4 -> 5 -> null?Solution
Step 1: Identify the reorder pattern
Reorder means first node, last node, second node, second last node, and so on.Step 2: Apply pattern to given list
For 1->2->3->4->5, reordered is 1->5->2->4->3.Final Answer:
1 -> 5 -> 2 -> 4 -> 3 -> null -> Option AQuick Check:
Alternate front and back nodes = C [OK]
- Reversing entire list instead of reordering
- Keeping original order unchanged
- Skipping nodes or mixing order
def reorderList(head):
if not head or not head.next:
return
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
second = slow.next
slow.next = null
prev = null
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 = temp1
second = temp2
Solution
Step 1: Analyze function return behavior
The function modifies the list in place but does not return anything, which is acceptable if list nodes are modified directly.Step 2: Check if returning head is necessary
Since the list is modified in place, returning head is optional; however, if used in some contexts, returning head is safer.Step 3: Identify actual bug
All other parts correctly find middle, reverse second half, and merge. The main issue is no return statement if function expected to return head.Final Answer:
The function does not return the head after reordering -> Option AQuick Check:
Missing return statement = A [OK]
- Starting slow pointer at head.next causing wrong middle
- Merging loop condition incorrect causing infinite loop
- Ignoring single node edge case
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null. After applying the reorder linked list algorithm, what will be the final list? Also, explain why the middle node is chosen as it is.Solution
Step 1: Apply reorder pattern to even length list
For 1->2->3->4->5->6, reordered list is 1->6->2->5->3->4.Step 2: Explain middle node choice
Using slow and fast pointers, slow stops at the first middle node (3), splitting list into two halves evenly.Final Answer:
1 -> 6 -> 2 -> 5 -> 3 -> 4 -> null; middle chosen as the first of the two middle nodes -> Option CQuick Check:
Even length split uses first middle node = D [OK]
- Choosing second middle node as split point
- Not reordering even length lists
- Mixing node order in final list
Ready to prove it?
Pass the test and this pattern moves unknown
