[Algorithm] Three Number Sort
You're given an array of integers and another array of three distinct integers. The first array is guaranteed to only contain integers that are in the second array, and the second array represents a desired order for the integers in the first array. For example, a second array of [x, y, z] represents a desired order of [x, x, ..., x, y, y, ..., y, z, z, ..., z] in the first array.
Write a function that sorts the first array according to the desired order in the second array.
The function should perform this in place (i.e., it should mutate the input array), and it shouldn't use any auxiliary space (i.e., it should run with constant space: O(1) space).
Note that the desired order won't necessarily be ascending or descending and that the first array won't necessarily contain all three integers found in the second array—it might only contain one or two.
Example
array = [1, 0, 0, -1, -1, 0, 1, 1] order = [0, 1, -1]
Result:
[0, 0, 0, 1, 1, 1, -1, -1]
Solution 1:
Three pointers
// L = 0, M = 0, R = array.length -1
// start by moving M
// if current value === order[Middle]
// m++
// just move M because M wants to point to L value or R value
// then swap, so that we can make sure position L or R is in place
// if current value === order[0]
// swap m with L
// L++
// M++
// move L & M at the same time because at position L is already in place
// M cannot be smaller than L
// Else current value === order[last]
// only R--
// don't move M, because new M might need to be move again
function threeNumberSort(array, order) {
let l = 0;
let m = 0;
let r = array.length -1;
let [first, second, last] = order
while (m <= r) {
const val = array[m];
if (val === first) {
swap(array, m, l)
l++;
m++;
}
else if (val === second) {
m++
}
else {
swap(array, m, r--)
}
}
return array;
}
function swap(array, i, j) {
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
Solution 2:
Count each order occurrences
function threeNumberSort(array, order) {
const count = {}
let len = array.length;
const [first, second, last] = order;
for (let i = 0; i < array.length; i++) {
const val = array[i]
if (typeof count[val] === "undefined") {
count[val] = 1
} else {
count[val]++
}
}
let j = 0
for (let i = 0; i < array.length; i++) {
while(typeof count[order[j]] === "undefined") {
j++
}
const key = count[order[j]];
if (count[order[j]] > 0) {
array[i] = order[j];
count[order[j]]--;
if (count[order[j]] === 0) {
j++
}
}
}
return array;
}