2.4. partition list
This commit is contained in:
parent
9882f36537
commit
89d27e359e
|
|
@ -0,0 +1,71 @@
|
|||
# 2.4. Partition
|
||||
|
||||
## Partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to X
|
||||
|
||||
> The partition element x can appear anywhere in the 'right' partition, it doesn't need to appear between the left and right partitions. The additional spacing in the example below indicates the partition
|
||||
|
||||
Input: 3 --> 5 --> 8 --> 5 --> 10 --> 2 --> 1 (Partition 5)
|
||||
Output: 3 --> 1 --> 2 --> 10 --> 5 --> 5 --> 8
|
||||
|
||||
## Initial idea
|
||||
|
||||
This is list sorting right? Given we already have the x value at the beginning, if one node is found with a bigger value, 'send to back'? But sounds very inefficient.
|
||||
|
||||
## Hint 1
|
||||
|
||||
> There are many solutions, most of which equally optimal in runtime, some with shorter cleaner code. Can you brainstorm?
|
||||
|
||||
Very useful hint..... We have to iterate through the list anyway, we don't want to order just separate. We could create 2 lists and then append one to the other.
|
||||
|
||||
```java
|
||||
public void partition(Node a, int x){
|
||||
Node small = null;
|
||||
Node big = null;
|
||||
while (c.next != null){
|
||||
if (c.data < x) small.appendTotail(c);
|
||||
else big.appendTotail(c);
|
||||
c = c.next;
|
||||
}
|
||||
small.appendToTail(big);
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
O(2n) time and O(2n) space, do we need those temporary LinkedLists? Otherwise just keep a 'big' list and remove from the list, but \# operations is the same.
|
||||
|
||||
## Hint 2
|
||||
|
||||
> The elements don't have to stay in the same relative order, we only need to ensure that elements less than the pivot must be before elements greater than the pivot.
|
||||
|
||||
I assume the solution is somehow appending the nodes to specific nodes during O(n) but I can't crack it...
|
||||
|
||||
## Solution
|
||||
|
||||
In a linked list, rather than swapping and shifting elements, we can create two linked lists, one for elements less than `x`, another for elements greater than or equal. Iterate through list, add nodes to one list or the other, merge them in the end. Elements stay in their original order.
|
||||
|
||||
The solution uses 2 Nodes per list, start and end nodes. that's 4 variables. If there's no obligation to keep the elements 'stable', we can rearrange the elements by growing the list at the head and tail.
|
||||
|
||||
We start a new list using the existing nodes, elements bigger than the pivot element are put at the tail and the elements smaller at the head. Each time we insert an element, update the head or the tail.
|
||||
|
||||
```java
|
||||
public static LinkedListNode partition(LinkedListNode node, int x) {
|
||||
LinkedListNode head = node;
|
||||
LinkedListNode tail = node;
|
||||
|
||||
/* Partition list */
|
||||
while (node != null) {
|
||||
if (node.data < x) {
|
||||
/* Insert node at head. */
|
||||
node.next = head;
|
||||
head = node;
|
||||
} else {
|
||||
/* Insert node at tail. */
|
||||
tail.next = node;
|
||||
tail = node;
|
||||
}
|
||||
node = node.next;
|
||||
}
|
||||
tail.next = null;
|
||||
return head;
|
||||
}
|
||||
```
|
||||
Loading…
Reference in New Issue