题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
代码
1 基于partition函数 O(n)
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
// 必须检查k的大小否则出错!!!
if (input.size() == 0 || k > input.size() || k<=0)
return vector<int>();
int start = 0;
int end = input.size() -1;
int index = Partition(input,start,end);
while(index != k-1){
if(index < k-1){
start = index + 1; // k在index右边
index = Partition(input,start,end);
}
else{
end = index -1; // k在index左边
index = Partition(input,start,end);
}
}
// vector<int> ret(input.begin(),input.begin() + k);
vector<int> ret;
for (int i = 0; i < k; ++i) {
ret.push_back(input[i]);
}
return ret;
}
int Partition(vector<int> &data, int start, int end){
if(start > end)
return start;
int key = data[start]; // 取第一个值为参考值
while(start< end){
while(data[end] >= key && start < end) end--;
data[start] = data[end];
while(data[start] <= key && start<end) start++;
data[end] = data[start];
}
data[start] = key;
return start;
}
};
2 堆排序O(n logk)
思路二:利用堆排序,O(N logK),适合处理海量数据
(1) 遍历输入数组,将前k个数插入到推中;(利用multiset来做为堆的实现)
(2) 继续从输入数组中读入元素做为待插入整数,并将它与堆中最大值比较:如果待插入的值比当前已有的最大值小,则用这个数替换当前已有的最大值;如果待插入的值比当前已有的最大值还大,则抛弃这个数,继续读下一个数。
这样动态维护堆中这k个数,以保证它只储存输入数组中的前k个最小的数,最后输出堆即可。
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
{
vector<int> result;
int len = input.size();
if(input.empty() || k<=0 || len < k) return result;
multiset<int, greater<int> > leastNumbers; // 从大到小排序
multiset<int, greater<int> >::iterator iterGreater; // 定义迭代器
vector<int>::iterator iter = input.begin();
for(; iter != input.end(); ++iter)
{
// 将前k个数直接插入进multiset中,注意是小于K
if(leastNumbers.size() < k)
{
leastNumbers.insert(*iter);
}
else
{
// 因为设置的从大到小排序,故multiset中第一个位置的元素即为最大值
iterGreater = leastNumbers.begin();
// 如果input中当前元素比multiset中最大元素小,则替换;即保持multiset中这k个元素是最小的。
if(*iter < *(leastNumbers.begin()))
{
// 替换掉当前最大值
leastNumbers.erase(iterGreater);
leastNumbers.insert(*iter);
}
}
}
for(iterGreater = leastNumbers.begin();iterGreater!=leastNumbers.end();++iterGreater)
{
result.push_back(*iterGreater); // 将multiset中这k个元素输出
}
return result;
}
};