Partition list

LeetCode problem 86. Partition List

## Problem description

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.

Example 1

* **Input**: head = [1,4,3,2,5,2], x = 3
* **Output**: [1,2,2,4,3,5]

Example 2
* **Input**: head = [2,1], x = 2
* **Output**: [1,2]

## Analysis

We can maintain two temporary lists: one for the elements **smaller than target**, the other for elements greater than equal to target. Using two **dummy heads** makes the things easier.

* **Smaller-than list**: 0 (dummy head) → …
* **Greater-or-equal list**: 0 (dummy head) → …

Then we can use a single pointer `curr` to scan through each element in the original linked list. Depending on the value of this pointer, we can join the tail of the corresponding temporary list to the pointer node, and update the tail of that list accordingly.

* This works because although we are modifying existing nodes *in-place*, every time when we append to one of the temporarily lists by changing the `next` pointer, the tail node of that list **must have already been visited by the `curr` pointer**. Hence, the `curr` pointer will go over all the nodes of the lists in the *original order*, and visit each node *exactly once*.

After scanning through all the elements, we can join the two temporary lists together.

1. Join the tail of the smaller-than list to the *head* (next of dummy head) of the greater-than-or-equal list.
2. Set the `next` pointer of the tail of greater-than-or-equal list to `nullptr`. This step is necessary to prevent the joined list from forming cycles.

### Complexity analysis

#### Time complexity

* We need to go over each node in the original list exactly once. This results in **O(1)** time complexity of the whole algorithm.

#### Auxiliary space complexity

Stack
Temporary variables on stack:

* The two dummy heads.
* The two marker pointers in the two temporary lists, which are used to append nodes to them.
* The `curr` pointer to scan through the original linked list.

So the auxiliary space complexity on stack is **O(1)**.

Heap
We have just allocated the two dummy heads on the heap.
So the auxiliary space complexity on heap is **O(1)**.
Add them up
The total auxiliary space complexity is **O(1)**.
## Solution

### C++

```
/\*\*
 \* Definition for singly-linked list.
 \* struct ListNode {
 \* int val;
 \* ListNode \*next;
 \* ListNode() : val(0), next(nullptr) {}
 \* ListNode(int x) : val(x), next(nullptr) {}
 \* ListNode(int x, ListNode \*next) : val(x), next(next) {}
 \* };
 \*/
class Solution {
public:
 ListNode\* partition(ListNode\* head, const int& x) {
 // trivial cases
 if ((head == nullptr) || (head->next == nullptr)) {
 return head;
 }

 // maintain two temporary lists
 // one list for smaller-than-x elements
 ListNode smallerDummyHead(0);
 ListNode \*smallerTail = &smallerDummyHead;
 // the other for greater-than-or-equal-to-x elements
 ListNode greaterEqualDummyHead(0);
 ListNode \*greaterEqualTail = &greaterEqualDummyHead;

 // iterate from left to right
 // append to appropriate temporary list
 ListNode \*curr = head;
 while (curr != nullptr) {
 if (curr->val < x) {
 smallerTail->next = curr;
 smallerTail = smallerTail->next;
 curr = curr->next;
 }
 else {
 greaterEqualTail->next = curr;
 greaterEqualTail = greaterEqualTail->next;
 curr = curr->next;
 }
 }
 // break the linkage after the tail of greater-than-or-equal list
 greaterEqualTail->next = nullptr;
 // join the smaller list with the greater-than-or-equal list
 smallerTail->next = greaterEqualDummyHead.next;

 return smallerDummyHead.next;
 }
};

```

### Java

```
/\*\*
 \* Definition for singly-linked list.
 \* public class ListNode {
 \* int val;
 \* ListNode next;
 \* ListNode() {}
 \* ListNode(int val) { this.val = val; }
 \* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 \* }
 \*/
class Solution {
 public ListNode partition(ListNode head, int x) {
 // trivial cases
 if ((head == null) || (head.next == null)) {
 return head;
 }

 // maintain two temporary lists
 // one list for smaller-than-x elements
 ListNode smallerDummyHead = new ListNode(0);
 ListNode smallerTail = smallerDummyHead;
 // the other for greater-than-or-equal-to-x elements
 ListNode greaterEqualDummyHead = new ListNode(0);
 ListNode greaterEqualTail = greaterEqualDummyHead;

 // iterate from left to right
 // append to appropriate temporary list
 ListNode curr = head;
 while (curr != null) {
 if (curr.val < x) {
 smallerTail.next = curr;
 smallerTail = smallerTail.next;
 curr = curr.next;
 }
 else {
 greaterEqualTail.next = curr;
 greaterEqualTail = greaterEqualTail.next;
 curr = curr.next;
 }
 }
 // break the linkage after the tail of greater-than-or-equal list
 greaterEqualTail.next = null;
 // join the smaller list with the greater-than-or-equal list
 smallerTail.next = greaterEqualDummyHead.next;

 return smallerDummyHead.next;
 }
}

```

## Notes

* We can use the two **dummy heads** to make things easier, because when we iterate through the list, we do not know in advance when each of the temporary lists will be fed the first node.
* In C++ the two dummy heads must be explicitly deleted. But in Java, they will be garbage collected.