最小的K个数

来源:互联网 发布:培训java三个月靠谱吗 编辑:程序博客网 时间:2024/06/06 19:47

题目:输入n个整数,找出其中最小的K个数。例如输入4,5,1。6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

这道题类似于之前讲堆的那篇文章中,求公司员工喜欢的前K种水果,那道题我们可以使用最小堆解决,同样的思路,这道题我们可以使用最大堆解决,在最大堆中,根节点的值总是大于它的子树中任意节点的值。所以我们可以在O(1)时间内得到已有的K个数中的最大值,但需要O(logk)时间完成删除及插入操作。

这篇文章我们介绍另一种方法。
我们知道,STL中的容器set可以其中插入的元素进行排序,而multiset是一种允许数据冗余的set,且它们的底层都是红黑树,查找、删除和插入操作都只需O(logK)。

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include<vector>#include<set>  #include <functional>   // std::greaterusing namespace std;typedef multiset<int, greater<int>> inset;typedef multiset<int, greater<int>>::iterator setiterator;void GetLeastKNumbers(const vector<int>& data, inset& leastNumbers, int k){    leastNumbers.clear();    if (k < 1 || data.size() < k)        return;    vector<int>::const_iterator it = data.begin();    while (it != data.end())    {        if (leastNumbers.size() < k)        {            leastNumbers.insert(*it);        }        else        {            setiterator iterGreater = leastNumbers.begin();            if (*it < *iterGreater)            {                leastNumbers.erase(iterGreater);                leastNumbers.insert(*it);0            }        }    }}