题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路
代码可有两种思路:
1.基于Partition函数(快排关键函数),但会修改输入的数组,如面试官不允许则不能使用此方法
2.(代码使用,适合海量数据,不修改输入的数组,TC:O(nlogk))遍历数组时保存2个值(数组中的数字,出现的次数times)
注:
set/multiset:关联容器,二者的关键字即值(即只保存关键字),set不允许容器中有可重复的元素, multiset允许容器中有可重复的元素
红黑树:
堆:堆是具有下列性质的完全二叉树
最大堆(大顶堆):每个节点的值都大于或等于其左右孩子节点的值
最小堆(小顶堆):每个节点的值都小于或等于其左右孩子节点的值
代码实现:(基于multiset)
1.分别建立一个vector容器(题干要求)用于存放最终结果和一个multiset容器(可自动排序,代码中使用降序)用于存放临时结果.以及相应的迭代器
2.遍历输入的整数各元素并在每次遍历时判断临时容器中元素数量:
若小于k,则直接insert元素;否则(等于k)比较最大元素(降序时为首元素)与当前元素的大小,将小的置入临时容器中.
3.将临时容器中元素置入结果容器中,并返回结果
代码
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
//建立一个vector容器存放最终结果
vector<int> result;
//验证输入的合法性
if(input.size() < k || k < 1)
return result;
//定义一个multiset容器临时存放结果
intSet tmpResult;
//定义一个const类型迭代器读取input中元素
vector<int>::const_iterator iter = input.begin();
for(;iter != input.end();++iter)
{
//若容器内元素数量小于k,则数字直接放入容器中
if(tmpResult.size() < k)
tmpResult.insert(*iter);
//tmpResult容器内元素数量为k,则需判断此时容器内元素最大值和当前元素的大小关系
else
{
//若结果容器中首元素大于当前元素,则将当前元素置入结果容器中
if(*iter < *tmpResult.begin())
{
tmpResult.erase(tmpResult.begin());
tmpResult.insert(*iter);
}
}
}
//将multiset容器中的结果存放至vector容器中,从大到小输出
/*for(setIterator index = tmpResult.begin();index != tmpResult.end();++index)
{
result.push_back(*index);
}*/
//从小到大输出
for(setIterator index = tmpResult.end(); index != tmpResult.begin();--index)
{
result.push_back(*index);
}
return result;
}
private:
typedef multiset<int, greater<int> > intSet;
typedef multiset<int, greater<int> >::const_iterator setIterator;
};