【剑指offer】面试题30:最小的 k 个数

时间:2022-12-23 20:59:10

题目:

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

思路:

这个是O(nlogk)时间复杂度的思路:用一个容器来保存最先的k个数,这样每次来一个数时,用这个数和容器中k个数中的最大值进行比较;如果比最大值大,则舍弃;比最大值小,则删除最大值,并将该值加入容器。那么问题就是应该选用什么样的容器?

容器需要做3件事:一是在k个数中找最大值,二是删除最大值,三是插入新数。如果用二叉树来实现这个容器,则可以在O(logk)的时间内实现这三个步骤。可以选用红黑树,STL中的set和multiset都是基于红黑树实现。

注意:

考虑无效输入时,也要记得考虑k;

multiset的插入是insert操作,删除是erase操作,遍历和取值是迭代器、没有下标操作符[]。

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(k<1 || input.size()<k) return res; multiset<int,greater<int> > leastNumbers;
for(int i=;i<input.size();++i)
{
if(leastNumbers.size()<k)
{
leastNumbers.insert(input[i]);
}
else if(input[i]<*leastNumbers.begin())
{
leastNumbers.erase(leastNumbers.begin());
leastNumbers.insert(input[i]);
}
} for(multiset<int,greater<int> >::iterator iter=leastNumbers.begin();iter!=leastNumbers.end();
++iter)
{
res.push_back(*iter);
}//可以新建一个vector,用vector的构造函数 vector<int>  res2(leastNumbers.begin(),leastNumbers.end()); return res;
}
};