Given is:
- An array of length
N. - The array contains integers.
- The integers are not necessarily sorted.
Find an algorithm that:
- Returns (a close approximation of)the
K-th smallest array element. - Has a runtime complexity of O(
NlogN) and a space complexity of O(logN). - The algorithm needn't be deterministic. In case of a probabilistic algorithm also provide a measure for the quality of the approximated result.
-
3Please add more information. What's the "selection algorithm" being modified? Also, if it's homework you should tag it as such.payne– payne2011年02月19日 01:45:57 +00:00Commented Feb 19, 2011 at 1:45
-
Selection algorithm is an algorithm to select kth order element in an array without sorting it.Algos– Algos2011年02月19日 01:47:57 +00:00Commented Feb 19, 2011 at 1:47
-
5@Algos - is this homework? (If it is, then I'm sure that the point of it is to get you to work the answer out for yourself.)Stephen C– Stephen C2011年02月19日 01:53:14 +00:00Commented Feb 19, 2011 at 1:53
-
yes its a homework.. stuck thr for a long time .. so I was looking for some hint .Algos– Algos2011年02月19日 01:56:06 +00:00Commented Feb 19, 2011 at 1:56
-
1we need a randomized algorithm with O (n log n ) time in high probabilityAlgos– Algos2011年02月19日 02:07:36 +00:00Commented Feb 19, 2011 at 2:07
4 Answers 4
Treat the problem as something analogous to Quicksort. Given an element in the array, you can get its rank in O(n) time and O(lg n) space. You can use binary search to find an element with a given rank in O(lg n) iterations of that, for a total of O(lg n) space and O(n lg n) time.
13 Comments
lo and hi) and their ranks (lo_rank and hi_rank). Label A: Then, pick some element m between lo and hi (in O(n) time) and compute its rank m_rank (in O(n)). If m_rank == k, we are done. If m_rank < k, replace lo and lo_rank with m and m_rank respectively and go to A; if m_rank > k, do the same with hi and go to A.- Iterate over the array once to find the
minimumandmaximumelement. - Iterate over the array to find a random element
pivotbetweenminimumandmaximum(exclusive). - Iterate over the array and count the number of elements less than or equal to
pivot(numSmallerEqual) and the number of elements greater thanpivot(numBigger).- If K <=
numSmallerEqual, setmaximum=pivot. - Else set
minimum=pivot.
- If K <=
- If (
maximum-minimum)==0, outputminimum, terminate. - If (
maximum-minimum)==1- If K <=
numSmallerEqual, outputminimum. - Else output
maximum. - Terminate.
- If K <=
- GOTO 2:
EDIT: Corrected the error pointed out by lVlad, still not tested.
14 Comments
1 3, k = 2. pivot = 2, minimum = 1, maximum = 3, numSmallerEqual = 1, minimum = 2. pivot = 2, numSmallerEqual = 1, minimum = 2 ... infinite loop.O(n log v), where v is the difference between the maximum and minimum values of the array, not O(n log n). v can be independent of n.Don't construct partitions. Describe what the partitions are (in constant space), and recursively select on this.
Each subarray that quickselect recurses into can be described by its bounds (min and max element values, not their indexes). Iterating over a subarray so described requires O(n) comparisons, which are made at every recursion level, up to the same depth as in quicksort: O(log n) in the average case.
Quicksort also makes O(n) comparisons at every recursion level, while ordinary permuting quickselect makes O(n) comparisons in total in the average case (because it always recurses into only one partition).
Here's a sample implementation for distinct elements with an ordinary quickselect implementation for comparison.
18 Comments
lo and hi are element values. I will iterate over all n elements of the original array in each step, but I will ignore those x that don't satisfy lo ≤ x ≤ hi.You can take the parameterization approach:
Since we have k specified in the problem, we can treat it as a constant, thus space of O(k log N) should be acceptable.
- Divide the array into
kpartitions of equal length (O(1) time and O(klogN) space to store the partition borders because each key should only require logNspace) - Find the smallest element in each partition (O(
N) time and O(klogN) space to store the smallest elements - return the max of the k elements you have (O(
k) time)
Since there's room for more cycles in there, there's probably a better way to do it. Also note that this would perform very poorly on an array that is sorted...