最小的K个数
1.题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
2.方法1(快排)
基于partition,返回下标index,如果下标大于k-1,则从k-1往后继续执行partition,否则从0~k-1执行partition。直到index等于k-1。
3.代码
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.empty() || k <= 0 || k > input.size()){
return res;
}
int left = 0;
int right = input.size() - 1;
int index = partition(input,left,right);
while(index != k-1){
if(index > k - 1){
right = index - 1;
index = partition(input,left,right);
}
else{
left = index + 1;
index = partition(input,left,right);
}
}
for(int i = 0;i < k;++i){
res.push_back(input[i]);
}
return res;
}
int partition(vector<int>& nums, int left, int right){
int t = left;
for(int i = left;i < right;++i){
if(nums[i] < nums[right]){
swap(nums[t++],nums[i]);
}
}
swap(nums[t],nums[right]);
return t;
}
};
4.复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
5.方法2(最大堆)
用数组的元素构建一个大小为k的最大堆,剩下的元素依次和堆顶元素比较,如果小于堆顶元素,则删除堆顶元素,并且插入该元素,堆会自动调整为最大堆。大于堆顶元素则抛弃。遍历完成后,得到的堆是数组最小的k个元素。
6.代码
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.empty() || k <= 0 || k > input.size()){
return res;
}
multiset<int,greater<int>> max_heap;
for(int i = 0;i < input.size();++i){
if(i < k){
max_heap.insert(input[i]);
}
else{
multiset<int,greater<int>> ::iterator max = max_heap.begin();
if(input[i] < *max){
max_heap.erase(max);
max_heap.insert(input[i]);
}
}
}
for(auto iter = max_heap.begin();iter != max_heap.end();++iter){
res.push_back(*iter);
}
return res;
}
};
7.复杂度分析
时间复杂度:O(nlogk)
空间复杂度:O(n)