数组计数法
#include<iostream>
using namespace std;
int main()
{
int n,k,b[100000],a[100000];
int count=0;
scanf("%d%d",&n,&k);//输入n和k
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[a[i]]++;
}
for(int i=1;i<=n;i++)
{
if(b[i]>=1) count++;//由于相同的数存在一个数组里,所以不用去重
if(count==k) {
printf("%d",i);
return 0;
}//找出第k小,输出
}
printf("NO RESULT");//否则找不出第k小
return 0;
}
非常好理解
sort法
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int n,x,y;
int a[100000];
scanf("%d%d",&n,&x);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
for(int i=1;i<=x;i++){
if(a[i]==a[i+1]) x=x+1;
y=i;
}
if(y>n) printf("NO RESULT");
else printf("%d",a[y]);
}
快选做法
时间复杂度O(2n).
这个好像没过555我也不知道为什么
#include <iostream>
using namespace std;
int n,k;
int q[100010];
int quick_sort(int l,int r,int k){
if(l==r) return q[l];
int x=q[l],i=l-1,j=r+1;
while(i<j){
while(q[++i]<x);
while(q[--j]>x);
if(i<j) swap(q[i],q[j]);
}
int sl=j-l+1;
if(k<=sl) return quick_sort(l,j,k);
return quick_sort(j+1,r,k-sl);
}
int main(){
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>q[i];
}
cout<<quick_sort(0,n-1,k)<<endl;
return 0;
}
- 找到分界点x ,可以是q[l] , q[r] , q[(l+r)/2]
- 分成左右两个区间,左边left <=x,右边right >=x
- 递归左边,递归右边
设左边有 sl 个数
如果k<=sl,说明第k小个数在左边,则只需递归左边left
如果k>sl,说明第k小个数在右边,递归右边right.因k为整个区间第k小,在右区间则为第k-sl小