The complexity of nth_element is O(N).
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
int main() {
int K;
cin >> K;
vector<int> numbers((istream_iterator<int>(cin)),
istream_iterator<int>());
nth_element(numbers.begin(), numbers.begin() + K, numbers.end(),
greater<int>());
for (int i = 0; i < K; ++i) {
cout << numbers[i] << ' ';
}
cout << '\n';
}
Input: 5
1 9 1 3 7 8 2 11 2 5 5 9 1 7
Output: 7 9 9 11 8
Note: the output is not sorted.in mine (osx 10.6.7, g++ 4.2.1), it's in
/usr/include/c++/4.2.1/bits/stl_algo.h
and it uses an algorithm very similar to the original article
If you look there, you will see it internally uses a heap.
template<typename _RandomAccessIterator>
inline void
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
__glibcxx_requires_valid_range(__first, __nth);
__glibcxx_requires_valid_range(__nth, __last);
if (__first == __last || __nth == __last)
return;
std::__introselect(__first, __nth, __last,
std::__lg(__last - __first) * 2);
}It seems to me that if you know the K'th largest, it's O(N); but otherwise, it's harder.
Finding the kth largest element can be done in O(N) time.
Obviously, as k approaches n, this algorithm is in reality O(n^2)
In fact, this can be done in O(n) time even if k isn't constant: use the selection algorithm to find the k'th largest element (in O(n) time) and then go through the list again and output every number that's k or larger.
It's typically easy to reduce solving such a problem with duplicates allowed into a very similar one without duplicates. Just replace every element x by the ordered pair (x, the position in the array where x came from) and then use a modified comparison function that sorts according to the second element in the pair if two ordered pairs are equal in the first element.
There are N elements in the sequence, and you can arrange for the sorting to be a single-step bubble sort, so that the total cost is O(K) operations per element --> O(NK) overall. Noting that K is constant, it's O(N).
Note that this really assumes K is constant. If K is depends on N, then the array A will expand