Here's another algorithm, the cost is going to be O(n) for any k
, plus a decent cache locality.
1.First store all elements in a unordered_map
O(N)
std::unordered_map<int, int> m;
for(const auto ele: numbers) {
m[ele]++;
}
2.Dump all elements in a vector of pairs O(N)
std::vector<std::pair<int, int>> temp;
for(const auto& ele: m) {
temp.emplace_back(ele.first , ele.second);
}
3.Now use the nth_element to find kth rank O(N)
std::nth_element( temp.begin(), temp.begin()+k ,
temp.end(), [](const auto& p1, const auto& p2) {
// Strict weak ordering
if (p1.second > p2.second) {
return true;
} if (p1.second < p2.second) {
return false;
}
return p1.first > p2.first; // We have to print large element first
} );
4.Display the output
std::for_each( temp.begin(), temp.begin() +k - 1, [](const auto & p) {
std::cout << p.first << " ";
});
Demo Here