Is there an algorithm to split a sequence of random numbers into two groups based on a median value determined on the fly(without sorting them)?
Ex. If I have the sequence 2-3-6-7-1-4-5, the result would be two separated groups:
A) 1 2 3
B) 5 6 7
Median value: 4
Yes, this can be done in O(n).
First of all, if we already knew the median, we could easily split the sequence in two in O(n) by iterating the sequence and comparing each value with the median. So how do we find the median in O(n)?
The basic idea is to use quicksort, but instead of recursively sorting both sides of the pivot, only sort the half that contains the median (ie. the half that encompasses the index
⌈n/2⌉). If our selection of a pivot guarantees geometric convergence of quicksort (like median-of-medians does), then our overall algorithm will be O(n).Algorithm
Let’s call the current size of our array k, and the reduction due to median-of-medians c – ie. our pivot guarantees the array shrinks by a factor of at least c each step
⌈n/2⌉). This new sub-array will have size no greater thank/c. Repeat steps 1 & 2 recursively until we’ve determined the element whose position in the original array is⌈n/2⌉.The asymptotic running time of this algorithm is
2 O(n) + 2 O(n/c) + 2 O(n/c2) + 2 O(n/c3) + …
= O(n)