先创建一个大小为K的数据容器来存储最小的K个数,接下来我们每次从输入的n个整数中读入一个数,如果容器中已有的数字少于K,则直接把这次读入的整数放入容器中;如果容器中已有K个数,就是容器满了,此时我们不能插入新的数字而只能替换已有的数字了。找出这K个数的最大值,然后拿这次待插入的整数和最大值相比较。如果待插入的值比当前已有的最大值小,则用这个数替换当前已有的最大值;如果待插入的值比当前已有的最大值还大,那么这个数不可能是最小的K个整数之一,于是我们可以抛弃这个数。
我们可以用二叉树(红黑树或最大堆)来实现这个数据容器。堆查找最大值O(1),删除插入为O(logk);红黑树查找、删除和插入都是O(logk)。
第2种情况非常适合海量数据的处理,当n>>k的时候非常适合。
时间复杂度为:O(n*lgk)
#include <iostream>
#include <set>
#include <vector>
using namespace std;
typedef multiset<int,greater<int> > intSet;
typedef multiset<int,greater<int> >::iterator setIterator;
void MinK(const vector<int>& data,intSet& leastNumbers,int k) {
leastNumbers.clear();
if(k < 1 || data.size() < k)
return;
vector<int>::const_iterator iter = data.begin();
for(; iter != data.end(); ++ iter) {
if(leastNumbers.size()<k) {
leastNumbers.insert(*iter);
}
else {
setIterator iterGreatest = leastNumbers.begin();
if(*iterGreatest > *iter) {
leastNumbers.erase(iterGreatest);
leastNumbers.insert(*iter);
}
}
}
}