题目:给定无序序列,要求输出第k小的数字
tip1:排序完直接选第k小的数字 O(nlog(n))
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
int n,k;
cin>>n>>k;
int b[n];
for(int i=0; i<n; ++i)
cin>>b[i];
sort(b,b+n);
cout<<b[k-1];
}
tip2:用堆的思想 O(nlog(n))
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int main() {
int n,k;
cin>>n>>k;
priority_queue<int,vector<int>,greater<int>> q;
for(int i=0; i<n; ++i) {
int t;
cin>>t;
q.push(t);
}
while(--k)
q.pop();
cout<<q.top();
}
tip3:从序列中选取一个数当作mid,然后将序列按小于等于和大于等于mid分为两部分,根据第一部分的元素个数决定第k小的数字在前半段部分还是后半段部分,然后分情况讨论递归左右子区间。O(n)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a;
void quick_select(int l,int r,int k) {
int i=l,j=r,mid=(l+r)/2;
do {//分类
while(a[i]<a[mid])++i;
while(a[j]>a[mid])--j;
if(i<=j) {
swap(a[i],a[j]);
++i;
--j;
}
} while(i<=j);
if(j>=l&&k<j-l+1)//所在区间讨论
quick_select(l,j,k);
else if(i<=r&&k>i-l+1)
quick_select(i,r,k-(i-l));
}
int numK(int l,int r,int k) {
quick_select(l,r,k);
return a[k-1];
}
int main() {
int n,k;
cin>>n>>k;
a.resize(n);
for(int i=0; i<n; ++i)
cin>>a[i];
cout<<numK(0,n-1,k);
return 0;
}