0

Possible Duplicate:
Worst-case O(n) algorithm for doing k-selection

Given the following question :

In an integer array with N elements , find the minimum k elements (k << N)

You can assume that N is a large number.

I'm thinking about a minimum heap , anyone has a better solution ?

Regards

Community
  • 1
  • 1
JAN
  • 18,509
  • 49
  • 147
  • 268

3 Answers3

5

If K << N, min heap is good enough because creation of heap is O(n), and if K << N selecting first K items is at most O(N), otherwise you could use selection algorithm to find Kth smallest element in O(n) then select numbers which are smaller than found item. (Sure if some numbers are equal to Kth element select till fill K items).

Saeed Amiri
  • 21,361
  • 5
  • 40
  • 81
  • A min heap might actually be slower than a naive implementation. I know for a fact that it's slower if k == 1. – Wug Aug 21 '12 at 14:40
  • @SaeedAmiri: After finding the `Kth` smallest number , then I should use the Partition algorithm ? – JAN Aug 21 '12 at 14:40
  • @ron After you find the `Kth` smallest number, all you need to do is iterate the array again and any number `< Kth smallest` is in your solution, until you have `k` items. So `O(n) + O(n) = O(2n) ~ O(n)` – NominSim Aug 21 '12 at 14:43
  • @ron, just iterate array, and select numbers which are smaller than or equal to Kth smallest number, then if number of found item is bigger than `K` drop some items which are equal to Kth smallest number. – Saeed Amiri Aug 21 '12 at 14:43
  • @Wug, Sure for K=1,2,3 creating heap is not good, but when we don't know anything about `K` except `K << N`, we can't trust naive approach. e.g K = sqrt(N) << N, but naive approach causes to `n sqrt(n)` but heap is less than `O(n logn)` – Saeed Amiri Aug 21 '12 at 14:45
  • You can do this with an algorithm that runs in O(N*log(K)) time. Using an unmodified heap is O(N*log(N)). If you bound the heap (i.e. give it a maximum size of K) then the insertion time for it is O(log(K)). – Wug Aug 21 '12 at 14:52
  • @Wug, I offered an algorithm in O(N), heap is simple for implementation so I offered it as first option, also it's not `O(N log N)` it's O(N + k * log(N)) . Be careful creating heap of size `N` is O(N) not O(nlogn), deleting from heap takes time. – Saeed Amiri Aug 21 '12 at 14:55
  • @SaeedAmiri: depends on the heap implementation. Insertion into a binary heap is O(log(N)). http://en.wikipedia.org/wiki/Heap_(data_structure) – Wug Aug 21 '12 at 15:01
  • @Wug, I'm talking about creating heap not inserting in heap of size `n`, please check CLRS or other algorithmic text books too see why creating (min) heap is `O(n)`. If you couldn't find it, ask it in another question I'll answer it (but better place for this question is cs.stackexchange.com). – Saeed Amiri Aug 21 '12 at 17:22
  • OK, but that still leaves the disadvantage of either needing to reorder the array (which may not be an option) or to duplicate it. – Wug Aug 21 '12 at 17:26
0

What about this:

Sort the array (quicksort or heapsort are great for integer arrays), and iterate to k

Carlos Grappa
  • 2,291
  • 12
  • 17
0

I think you can do this one in O(N*log(K)). Pseudocode:

haz array[N]
haz output[k] (itz a list)

i iteratez on array with array[N] az element:
    i insertz element into output (i maintainz strict ordering)
    i removez largest element of output when output size iz bigger than k

Requires:

  • N list removals from end (N * O(1))
  • at most N sort-maintaining list inserts (N * O(log(listsize)))

list's size is bounded by K

Thus, O(N * log(K)) time.

Wug
  • 12,063
  • 4
  • 28
  • 52