Problem
Given the head
of a linked list and a value x
, partition it such that all nodes less than x
come before nodes greater than or equal to x
.
You should preserve the original relative order of the nodes in each of the two partitions.
Examples
Example 1:
--- title: Input --- graph LR A1[1]:::less --> B4[4]:::greater --> C3[3]:::pivot --> D2[2]:::less --> E5[5]:::greater --> F2[2]:::less classDef pivot fill:#ffb6c1,stroke:#000,stroke-width:2px; classDef less fill:#ffcc00,stroke:#000,stroke-width:2px; classDef greater fill:#add8e6,stroke:#000,stroke-width:2px;
--- title: Output --- graph LR A1[1]:::less --> D2[2]:::less --> F2[2]:::less --> B4[4]:::greater --> C3[3]:::pivot --> E5[5]:::greater classDef pivot fill:#ffb6c1,stroke:#000,stroke-width:2px; classDef less fill:#ffcc00,stroke:#000,stroke-width:2px; classDef greater fill:#add8e6,stroke:#000,stroke-width:2px;
Input: head = [1,4,3,2,5,2], x = 3
Output: [1,2,2,4,3,5]
Example 2:
--- title: Output --- graph LR A2[2]:::pivot --> B1[1]:::less classDef pivot fill:#ffb6c1,stroke:#000,stroke-width:2px; classDef less fill:#ffcc00,stroke:#000,stroke-width:2px;
--- title: Output --- graph LR B1[1]:::less --> A2[2]:::pivot classDef pivot fill:#ffb6c1,stroke:#000,stroke-width:2px; classDef less fill:#ffcc00,stroke:#000,stroke-width:2px;
Input: head = [2,1], x = 2
Output: [1,2]
Solution
Method 1 - Use 2 Fake Pointers
Here is how we can solve it (take list as [1,4,3,2,5,2]
)
- Initialize Two Dummy Nodes:
- Use two dummy nodes to maintain two separate lists: one for nodes less than
x
and one for nodes greater than or equal tox
. lessHead
for nodes less thanx
andgreaterHead
for nodes greater than or equal tox
.
- Use two dummy nodes to maintain two separate lists: one for nodes less than
- Traverse the List:
- Traverse the linked list and partition the nodes into the two separate lists based on their values.
- Connect nodes with values less than
x
to theless
list. - Connect nodes with values greater than or equal to
x
to thegreater
list.less = [1, 2, 2]
andgreater = [4, 3, 5]
- Since we traverse the original linked list sequentially from left to right, the relative order of the nodes remains unchanged within each of the two partitions.
- Combine the Two Lists:
- Attach the
greater
list to the end of theless
list. - Ensure the last node of the combined list points to null.
- output:
[1, 2, 2, 4, 3, 5]
- output:
- We did a dummy node initialization at the start to make implementation easier, you don’t want that to be part of the returned list, hence just move ahead one node in both the lists while combining the two list. Since both before and after have an extra node at the front.
- Attach the
Code
Java
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode lessHead = new ListNode(0);
ListNode greaterHead = new ListNode(0);
ListNode less = lessHead, greater = greaterHead;
while (head != null) {
if (head.val < x) {
less.next = head;
less = less.next;
} else {
greater.next = head;
greater = greater.next;
}
head = head.next;
}
// Terminate the greater list
greater.next = null;
// Connect less list with greater list
less.next = greaterHead.next;
return lessHead.next;
}
}
Python
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
less_head = ListNode(0)
greater_head = ListNode(0)
less = less_head
greater = greater_head
while head:
if head.val < x:
less.next = head
less = less.next
else:
greater.next = head
greater = greater.next
head = head.next
# Terminate the greater list
greater.next = None
# Connect less list with greater list
less.next = greater_head.next
return less_head.next
Complexity
- ⏰ Time complexity:
O(n)
, wheren
is the number of nodes in the linked list. The list is traversed once. - 🧺 Space complexity:
O(1)
as aux space, since only a constant amount of extra space is used for the pointers.
Note that we reuse nodes from the original linked list and reassign them to either the lessHead
or greaterHead
lists. This approach does not require extra space allocation for new nodes, as we are simply reordering the existing nodes. However, if the interviewer insists that the original list must remain unaltered, you can duplicate the nodes (by creating a new node) and perform operations on the new copies.