LeetCode #86 Medium

Partition List

Given the head of a linked list and a value x, partition it so that all nodes with values less than x come before nodes with values greater than or equal to x, preserving the original relative order within each partition.

linked-listtwo-pointers
Open on LeetCode ↗
02

Intuition

Think of it as building two separate linked lists — one for nodes less than x, one for nodes >= x — and then stitching them together. You do not need to move nodes in place or swap values. Walk through the original list once, appending each node to the appropriate sub-list. When done, connect the tail of the 'less' list to the head of the 'greater-or-equal' list. Dummy heads on both sub-lists eliminate all edge-case branching for empty partitions.

How to spot this pattern

When a linked list problem asks you to reorder nodes based on a condition while preserving relative order within each group, the pattern is: build separate sub-lists with dummy heads, route each node, then stitch. This avoids complex in-place pointer surgery and keeps the logic linear and clear.

03

Approach

1

Create two dummy-headed sub-lists for the two partitions

Allocate two dummy nodes: less_dummy for nodes with val < x, and geq_dummy for nodes with val >= x. Maintain tail pointers less_tail and geq_tail for appending. Dummy heads mean you never have to check whether the sub-list is empty before appending.

2

Walk the original list and route each node

For each node, compare its value to x. If less, append to less_tail and advance less_tail. Otherwise, append to geq_tail and advance geq_tail. Advance head to the next node. After the loop, every node has been moved to one of the two sub-lists.

3

Stitch the two sub-lists and terminate

Set less_tail.next = geq_dummy.next to connect the less partition to the greater-or-equal partition. Crucially, set geq_tail.next = None to terminate the list — without this, the last node in the geq partition still points to its old successor, creating a cycle. Return less_dummy.next.

04

Solution

1class Solution:
2 def partition(self, head, x):
3 less_dummy = ListNode(0)
4 geq_dummy = ListNode(0)
5 less_tail = less_dummy
6 geq_tail = geq_dummy
7 while head:
8 if head.val < x:
9 less_tail.next = head
10 less_tail = less_tail.next
11 else:
12 geq_tail.next = head
13 geq_tail = geq_tail.next
14 head = head.next
15 geq_tail.next = None
16 less_tail.next = geq_dummy.next
17 return less_dummy.next
05

Common pitfalls

Forgetting to set geq_tail.next = None to avoid a cycle

✗ Wrong
less_tail.next = geq_dummy.next
return less_dummy.next
✓ Right
geq_tail.next = None
less_tail.next = geq_dummy.next
return less_dummy.next

The last node in the geq partition still has its old .next pointer, which may point back into the less partition. Without nullifying it, the list has a cycle and traversal loops forever.

Using >= instead of < for the less partition check

✗ Wrong
if node.val <= x:
    less_tail.next = node
✓ Right
if node.val < x:
    less_tail.next = node

Nodes equal to x should go in the geq partition, not the less partition. Using <= pulls x-valued nodes into the wrong group, changing the output order.

Not advancing the original head pointer during traversal

✗ Wrong
while head:
    if head.val < x:
        less_tail.next = head
        less_tail = less_tail.next
    head = head.next
✓ Right
while head:
    if head.val < x:
        less_tail.next = head
        less_tail = less_tail.next
    else:
        geq_tail.next = head
        geq_tail = geq_tail.next
    head = head.next

Forgetting the else branch drops all geq nodes. They are never appended to the geq sub-list and are lost.

06

Edge cases

All nodes are less than x

The geq sub-list is empty. less_tail.next = geq_dummy.next = None, so the list is just the less partition.

All nodes are >= x

The less sub-list is empty. less_dummy.next = geq_dummy.next, returning the geq partition directly.

Empty list

The loop does not run. less_dummy.next is None. Correct.

07

Complexity

Time
O(n)
Space
O(1)
Single pass. Only two dummy nodes allocated; all original nodes are relinked in place.