AlgoMaster Logo

Partition List

Last Updated: March 29, 2026

medium
3 min read

Understanding the Problem

This problem is essentially asking us to do a stable partition on a linked list. We need to split the nodes into two groups based on a threshold value x: nodes with values less than x, and nodes with values greater than or equal to x. Within each group, the original order must be preserved.

The word "preserve" is critical here. If we just moved nodes around carelessly, we might get all the right values in the right half, but in the wrong order. For example, with [1, 4, 3, 2, 5, 2] and x = 3, we can't output [2, 2, 1, 3, 5, 4] even though that also has all the "less than 3" values first. The relative order within each group has to match the original list.

The key observation is that we're not sorting. We're partitioning. Two nodes that are both less than x should appear in the same relative order as they did in the original list. This means we need a stable approach, not just any rearrangement.

Key Constraints:

  • 0 <= n <= 200 -> With at most 200 nodes, even an O(n^2) solution would be nearly instant. But there's no reason to go beyond O(n) for a linked list partition.
  • -100 <= Node.val <= 100 -> Small value range. Values can be negative, and they can equal x. The condition is strictly "less than," so nodes equal to x go into the "greater than or equal to" group.
  • -200 <= x <= 200 -> The partition value x might not even appear in the list. It could also be smaller than all values or larger than all values.

Approach 1: Collect into Array and Rebuild

Intuition

The most straightforward way to think about this: traverse the linked list, collect all node values into an array, partition the array (preserving order), and then build a new linked list from the partitioned values.

This sidesteps all the tricky pointer manipulation. We just work with arrays, which are easier to reason about, and then convert back.

Algorithm

  1. Traverse the linked list and collect all values into an array.
  2. Create two arrays: one for values less than x, one for values greater than or equal to x.
  3. Concatenate the two arrays (less-than first, then greater-or-equal).
  4. Build a new linked list from the concatenated array and return it.

Example Walkthrough

Input:

1
4
3
2
5
2
null
head

After partitioning into two groups:

0
1
1
2
2
2
less
0
4
1
3
2
5
greater

Concatenate and rebuild:

1
2
2
4
3
5
null
result

Code

This approach works correctly but uses extra memory by creating new nodes. What if we rearranged the existing nodes by manipulating their next pointers instead?

Approach 2: Two Dummy Lists (Optimal)

Intuition

Instead of copying values, we can rewire the existing nodes into two separate chains. One chain collects all nodes with values less than x, and the other collects all nodes with values greater than or equal to x. Then we just connect the tail of the first chain to the head of the second chain.

The trick that makes this clean is using dummy head nodes. Without dummy nodes, we'd need special-case logic for the first node added to each chain. A dummy node acts as a placeholder so we can always append to tail.next without checking if the chain is empty.

Algorithm

  1. Create two dummy nodes: lessHead and greaterHead. These will serve as the anchors for our two chains.
  2. Initialize two tail pointers: lessTail and greaterTail, both pointing to their respective dummy nodes.
  3. Traverse the original list. For each node:
    • If node.val < x, append it to the "less" chain.
    • Otherwise, append it to the "greater" chain.
  4. Connect the two chains: set lessTail.next = greaterHead.next (skip the dummy).
  5. Terminate the list: set greaterTail.next = null to avoid cycles.
  6. Return lessHead.next (skip the dummy).

Example Walkthrough

1Initialize: two dummy heads, current at node 1
1
current
4
3
2
5
2
null
1/6

Code