题目描述
输入 n(1≤n<5000000 且 n 为奇数)个数字 ai(1≤ai<10^9),输出这些数字的第 k 小的数。最小的数是第 0 小。
输入输出样例
输入 #1
5 1 4 3 2 1 5
输出 #1
2
分析 :
这道题的数据非常大,先排序一遍再输出时间复杂度是O(nlog n),这显然是不行的。我们可以借助快速排序的思想,利用二分使每次处理的区间长度减半,降低时间复杂度至线性。
代码如下:
#include<iostream>
using namespace std;
const int N=1e7;
int a[N];
int n,k;
void find(int l,int r)
{
if(l>=r) return;
int i=l,j=r,mid=a[l+r>>1];
while(i<=j)
{
while(a[i]<mid) i++;
while(a[j]>mid) j--;
if(i<=j)
{
swap(a[i],a[j]);
i++;
j--;
}
}
if(k<=j) find(l,j);
else if(i<=k) find(i,r);
else find(j+1,i-1);
}
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
find(0,n-1);
cout<<a[k];
return 0;
}