Intuition
This question is one step of quick sort: split the list into two parts by a sentinal. We need three pointers to deal with the classifying process:
- One pointer denotes the right border of the smaller part, at first it’s at the dummy node before head node;
- The other two pointers are for one goal: iterate over the entire list, move node into the smaller part or remain at its original place up to the given sentinal
x
.Keep in mind we need two pointers to remove a node. The critial idea of this algorithm is to remove a node from the list and then insert it the the right border of the smaller part(after the slow pointer).
Algorithm
Let’s look at an example below:
Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5
The three pointers stated above are denoted bys
(slow), f
(fast), p
(pre, node before fast pointer).
- Initial State
-1(s,p)->1(f)->4->3->2->5->2
- Check the first node
Since 1 < 3
, we should remove fast node into smaller part, and then move fast node to next node. Here is a corner case, when fast node is right the next node of slow node, we don’t need to remove it from the list.
-1->1(s,p)->4(f)->3->2->5->2
- Check the second node
4>3
, so we don’t move any node, just move fast pointer and pre pointer to its next place
-1->1(s)->4(p)->3(f)->2->5->2
- Check the third node
The same case as the second one
-1->1(s)->4->3(p)->2(f)->5->2
- Check the fourth node
2<3
, we need to remove it from the list and insert it after slow pointer and then move two pointers to its next node. Take care that we don’t need to move pre pointer in this case.
-1->1->2(s)->4->3(p)->5(f)->2
- Check the nodes left
We will get the list finally(null
node after the tail node is ignored in previous diagram):
-1->1->2->2(s)->4->3->5(p)->null(f)
Code
1 | /** |
Complexity
Time Complexity: $O(n)$ It’s the cost of iterating over a list.
Space Complexity: $O(1)$ Constant pointers are used.