8

My initial algorithm:

  1. Compare element 0 with every other element, keeping track of how many elements are less than it.
  2. Repeat for each element until an element that is greater than exactly (k-1) elements is found.

I assume this would take $O(n^2)$ in the worst case. Can a faster runtime be achieved without sorting the list?

WHY
  • 213
  • 2
  • 4

4 Answers4

10

Use selection algorithm for linear time https://en.m.wikipedia.org/wiki/Selection_algorithm

Eugene
  • 1,106
  • 1
  • 6
  • 14
5

Unfortunately I can't just comment but I have to post it as an answer.

Anyway, you could try to use a min-heap on your unsorted array, you should be able to get a time complexity of O(n+k*logn).

Luca Giorgi
  • 201
  • 2
  • 6
3

The Quickselect algorithm can do that in O(n) average complexity, it is one of the most often used selection algorithm according to Wikipedia.

It is derived from QuickSort and as such suffers from a O(n²) worst case complexity if you use a bad pivot (a problem that can be avoided in practice).

The algorithm in a nutshell: After the pivoting like in QuickSort, only descend into either the lower or the higher side of the array - depending on which of them has the element you're after.

einpoklum
  • 1,025
  • 6
  • 19
2

Create a max-heap of size $k$. The invariant is that the heap always contains the $k$ smallest elements observed so far.

  1. Insert the first $k$ elements of the list into the heap
  2. For each remaining element $i$ in the list:
    • let $M$ be the maximum element in the heap
    • If $i < M$, then delete $M$ and insert $i$ into the heap

At the end, the heap will contain the $k$ smallest elements in the list.

Looking up the maximum element has constant cost. The cost of insertion and deletion is $O(k)$. The time complexity of this method is $O(n . \log k)$