题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
解题思路
此次使用不改变原数组的方法。使用c++STL中的set或者multiset来实现。这两个模板底层的实现都是红黑树。即平衡的二叉搜索树。以下是对set和multiset的简单介绍:
STL | 说明 |
set<T> | 按照从小到大顺序排列的set,元素不允许重复 |
set<T,op> | 按照op排列的set,元素不允许重复 |
multiset<T> | 从小到大顺序排列的mulitset,只是元素允许重复 |
multiset<T,op> | 按照op排列的set,元素允许重复 |
op如果是less<T>,就是从小到大;op是greater<T>就是从大到小。
遍历待选数组。
当set或者multiset的大小不大于k的时候,可以直接往里面添加元素;
但是当set或者multiset的大小等于k的时候,此时要将当前元素与容器中的最大的元素进行比较。如果大于,则进行下一轮循环;如果小于则将容器中的最大的元素删除掉,将当前元素插入容器。
代码实现
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
multiset<int,greater<int> > leastNumber;
if(k<1||input.size()<k){
return vector<int>();
}
for(vector<int>::iterator iter=input.begin();iter!=input.end();iter++){
if(leastNumber.size()<k){//如果set没有填满,则直接插入;
leastNumber.insert(*iter);
}
else{//如果set已经满了,则应该删除其中最大的。
multiset<int,greater<int> >::iterator setBegin=leastNumber.begin();
if((*iter)<*(leastNumber.begin())){
leastNumber.erase(setBegin);
leastNumber.insert(*iter);
}
}
}
vector<int> res(leastNumber.begin(),leastNumber.end());
return res;
}
};