剑指offer40 最小的k个数
输入n个整数,找出其中最小的k个数。
注意:
数据保证k一定小于等于输入数组的长度;
输出数组内元素请按从小到大顺序排序;
样例
输入:[1,2,3,4,5,6,7,8] , k=4
输出:[1,2,3,4]
思路1:
用大顶堆保存k个数,然后不断的遍历数组,若是数组中的数小于堆顶元素,则替换。实践复杂度为O(nlogk)。
AcWing-53 c++ code:
class Solution {
public:
vector<int> getLeastNumbers_Solution(vector<int> input, int k) {
if(input.size() < k){
return {};
}
int n = input.size();
priority_queue<int, vector<int>, less<int>> k_nums;
for(int i = 0; i < n; i++){
if(i < k){
k_nums.push(input[i]);
}else if(input[i] < k_nums.top()){
k_nums.pop();
k_nums.push(input[i]);
}
}
vector<int> res;
while(!k_nums.empty()){
res.insert(res.begin(), k_nums.top());
k_nums.pop();
}
return res;
}
};
思路2:
快速排序的思想。平均时间复杂度为O(n)。
c++ code:
class Solution {
public:
void QuickSort(vector<int> &nums, int k, int left, int right){
int midNum = nums[left];
int i = left, j = right;
while(j > i){
while(j > i && nums[j] > midNum){
j--;
}
swap(nums[i], nums[j]);
while(j > i && nums[i] < midNum){
i++;
}
swap(nums[i], nums[j]);
}
if(k < j + 1){
QuickSort(nums, k, left, j);
}else if(k > j + 1){
QuickSort(nums, k, j + 1, right);
}
}
vector<int> getLeastNumbers_Solution(vector<int> nums, int k) {
if(nums.size() == 0){
return {};
}
QuickSort(nums, k, 0, nums.size() - 1);
vector<int> res(nums.begin(), nums.begin() + k);
sort(res.begin(), res.end());
return res;
}
};
思路3:
先找出k个数,然后每遍历一次剩下的数的时候,如果该数小于k个数中的最大值,就把这个最大值替换掉。时间复杂度为O(nk)。
c++ code:
class Solution {
public:
vector<int> getLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.size() == 0){
return res;
}
int max;
int index;
for(int i = 0; i < input.size(); i++){
if(i < k){
res.push_back(input[i]);
continue;
}
max = res[0];
index = 0;
for(int i = 1; i < k; i++){
if(res[i] > max){
max = res[i];
index = i;
}
}
if(max > input[i]){
res[index] = input[i];
}
}
sort(res.begin(), res.end());
return res;
}
};