NC119最小的k个数
知识点:排序
题目链接
题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4
示例1
输入:[4,5,1,6,2,7,3,8],4
返回值:[1,2,3,4]
解题思路
- 直接使用快排 对整个数组排序
- 使用优先队列,如果队列中的数据小于K就往里放,否则和队列中的头部(也就是最大的那个)比较,哪个小就放入队列中,最后队列中的元素弹出就是答案
- 利用快排的思想 快排一次 能够使基准前面的数 都小于基准 后面的都大于基准,并且用二分法的思想定位需要排序的位置,
- 如果基准排序完所占位置+1 = k 就返回前面的k个数字
- 如果基准排完顺序 < k 则需要从基准后+1的位置 开始再排序,
- 如果基准排完顺序 > k, 则需要从头到基准 再排序
- 注意如果最后需要全部输出的情况
代码
#include "cheader.h"
class Solution {
public:
vector<int> GetLeastNumbers_Solution1(vector<int> input, int k) {
vector<int> ans;
if(k == 0 || k >input.size()) return ans;
sort(input.begin(), input.end());
return vector<int>({input.begin(),input.begin()+k});
}
vector<int> GetLeastNumbers_Solution2(vector<int> input, int k) {
vector<int> ans;
if(k == 0 || k >input.size()) return ans;
priority_queue<int,vector<int>,less<>> p;
for(int x:input){
if(p.size() < k)
p.push(x);
else if(x < p.top()){
p.pop();
p.push(x);
}
}
while(!p.empty()){
ans.push_back(p.top());
p.pop();
}
return ans;
}
vector<int> GetLeastNumbers_Solution3(vector<int> input, int k) {
vector<int> ans;
if(k == 0 || k >input.size()) return ans;
int l = 0, r = input.size()-1;
while(l < r){
int p = one_sort(input,l,r);
if(p+1 == k)
return vector<int>({input.begin(),input.begin()+k});
else if (p+1 < k)
l = p+1;
else
r = p;
}
return input; //输出所有
}
int one_sort(vector<int>& input,int l,int r){
int val = input[l];
int left = l,right = r;
while(left < right){
while(left < right && val <= input[right])
right--;
while(left < right && val >= input[left])
left++;
swap(input[left], input[right]);
}
swap(input[left],input[l]);
return left;
}
};
int main()
{
vector<int> input{4,5,1,6,2,7,3,8};
int k = 4;
Solution s;
vector<int> ans = s.GetLeastNumbers_Solution2(input, k);
for(int x:ans)
cout<<x<<endl;
return 0;
}
今天也是爱zz的一天!