This can be done in linear time using the selection algorithm , which takes O(n) in the worst case, and then passes through the vectors once and taking exactly those elements that are at least as large as statistics of the (nk) th order (and counting the number of elements you took so that you take exactly k and no more). However, Cppreference says that std::nth_element takes an average time, not the worst case. I will explain how to do this a little slower, but probably easier using heaps. This solution takes O(max(n,k*log(k))) time O(max(n,k*log(k))) in the worst case, to extract the top elements k vector of size n .
You start by creating a max heap with all n elements that take O (n) time with std::make_heap .
Now we want to extract the top elements of k from this heap, but we need to be smart when we do this. If we extract the maximum element k times, it will cost us O(log(n)) every time, so O(k*log(n)) as a whole, which does not achieve our goal.
Instead, we will not touch this heap of size n and create a separate maximum heap, which I call the "waiting heap". This heap of expectations begins only with the maximum element of the source heap, and to get the top k elements, you repeat the following procedure k times: extract the top element from the waiting heap and add your two descendants to it. The size of the expected heap increases by one at each step, so it is limited to k . Since we are rendering the k and 2k inserts (assuming you use the binary heap), this will cost us more than 3*k*log(k) .
source share