问题
is there a way to find the Median of an unsorted array: 1- without sorting it. 2- without using the select algorithm, nor the median of medians
I found a lot of other questions similar to mine. But the solutions, most of them, if not all of them, discussed the SelectProblem and the MedianOfMedians
回答1:
You can certainly find the median of an array without sorting it. What is not easy is doing that efficiently.
For example, you could just iterate over the elements of the array; for each element, count the number of elements less than and equal to it, until you find a value with the correct count. That will be O(n2) time but only O(1) space.
Or you could use a min heap whose size is just over half the size of the array. (That is, if the array has 2k
or 2k+1
elements, then the heap should have k+1
elements.) Build the heap using the first array elements, using the standard heap building algorithm (which is O(N)). Then, for each remaining element x
, if x
is greater than the heap's minimum, replace the min element with x
and do a SiftUp operation (which is O(log N)). At the end, the median is either the heap's minimum element (if the original array's size was odd) or is the average of the two smallest elements in the heap. So that's a total of O(n log n) time, and O(n) space if you cannot rearrange array elements. (If you can rearrange array elements, you can do this in-place.)
回答2:
There is a randomized algorithm able to accomplish this task in O(n)
steps (average case scenario), but it does involve sorting some subsets of the array. And, because of its random nature, there is no guarantee it will actually ever finish (though this unfortunate event should happen with vanishing probability).
I will leave the main idea here. For a more detailed description and for the proof of why this algorithm works, check here.
Let A
be your array and let n=|A|
. Lets assume all elements of A
are distinct. The algorithm goes like this:
- Randomly select
t = n^(3/4)
elements fromA
. - Let
T
be the "set" of the selected elements.SortT
. - Set
pl = T[t/2-sqrt(n)]
andpr = T[t/2+sqrt(n)]
. - Iterate through the elements of
A
and determine how many elements are less thanpl
(denoted byl
) and how many are greater thanpr
(denoted byr
). Ifl > n/2
orr > n/2
, go back to step 1. - Let
M
be the set of elements inA
in betweenpl
andpr
.M
can be determined in step 4, just in case we reach step 5. If the size ofM
is no more than4t
, sortM
. Otherwise, go back to step 1. - Return
m = M[n/2-l]
as the median element.
The main idea behind the algorithm is to obtain two elements (pl
and pr
) that enclose the median element (i.e. pl
< m
< pr
) such that these two are very close one two each other in the ordered version of the array (and do this without actually sorting the array). With high probability, all the six steps only need to execute once (i.e. you will get pl
and pr
with these "good" properties from the first and only pass through step 1-5, so no going back to step 1). Once you find two such elements, you can simply sort the elements in between them and find the median element of A
.
Step 2 and Step 5 do involve some sorting (which might be against the "rules" you've mysteriously established :p). If sorting a sub-array is on the table, you should use some sorting method that does this in O(slogs)
steps, where s
is the size of the array you are sorting. Since T
and M
are significantly smaller than A
the sorting steps take "less than" O(n)
steps. If it is also against the rules to sort a sub-array, then take into consideration that in both cases the sorting is not really needed. You only need to find a way to determine pl
, pr
and m
, which is just another selection problem (with respective indices). While sorting T
and M
does accomplish this, you could use any other selection method (perhaps something rici suggested earlier).
回答3:
A non-destructive routine selip() is described at http://www.aip.de/groups/soe/local/numres/bookfpdf/f8-5.pdf. It makes multiple passes through the data, at each stage making a random choice of items within the current range of values and then counting the number of items to establish the ranks of the random selection.
来源:https://stackoverflow.com/questions/33964676/find-the-median-of-an-unsorted-array-without-sorting