题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
解题思路
思路1:按递增排序,然后输出前k个数,简单粗暴,时间复杂度O(nlogn)
思路2:利用partition算法,找到第K大数,输出其左边K个数,时间复杂度O(n)
思路3:开一个规模为K的数组,遍历原数组,若辅助数组未存满K个数,那么直接将遍历到的数放入K数组中;若已经存满K个数,那么,拿当前遍历到的数 与 K数组中最大数进行比较,若当前数小于K中最大数,则将两者进行替换。否则,丢弃当前数,继续遍历,直到遍历完原数组。时间复杂度O(nlogK)
其中,对于K数组需要执行的操作是:1、找最大数;2、删除最大数;3、插入新数。
这三步可以用二叉树来实现,则时间复杂度O(logK)。
用STL的multiset来实现。还可以用大顶堆实现,但比较麻烦。
思路2的实现,参照前一篇博客:http://blog.csdn.net/tommyzht/article/details/47121997
实现代码:
class Solution {
public:
typedef multiset<int, greater<int>> inset;
typedef multiset<int, greater<int>>::iterator setIterator;
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
inset leastKnum;
leastKnum.clear();
vector<int> ans;
if(k<1 || input.size()<k)
return ans;
vector<int>::const_iterator iter = input.begin();
for(;iter != input.end(); iter++)
{
if((leastKnum.size()) < k)
leastKnum.insert(*iter);
else
{
setIterator iterGrest = leastKnum.begin();
if(*iter < *(leastKnum.begin()))
{
leastKnum.erase(iterGrest);
leastKnum.insert(*iter);
}
}
}
for(auto a : leastKnum)
ans.push_back(a);
return ans;
}
};