#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e5+10;
int vis[MAX_N];
int ans;
int solve(int l,int r)
{
int p = vis[l];
while(l<r)
{
while(l<r && vis[r]>=p)
r--;
swap(vis[r],vis[l]);
while(l<r && vis[l]<=p)
l++;
swap(vis[r],vis[l]);
}
vis[l] = p;
return l;
}
int qsort_k(int l,int r,int k)
{
if(l<r)
{
int t=solve(l,r);
if(t < k)
qsort_k(t+1,r,k);
else if(t == k)
ans = vis[k];
else
qsort_k(l,t-1,k);
}
//由于这里只进行了一次递归,在理想情况下时间复杂度T(n)=T(n/2)+n,T(1)=1;O(n)的时间复杂度
}
int main()
{
//快排思想求第k大的数
int n;//输入n个数
int k;
while(cin>>n>>k)
{
for(int i=0; i<n; i++)
cin>>vis[i];
qsort_k(0,n-1,k-1);
cout<<ans<<endl;
}
return 0;
}
基本思想:
由于快排的partition函数返回的枢轴位置刚好是左边都比他小,右边都比他大,那我们可以利用这一特点,将其与K比较,可以减少一次递归;假如返回的枢轴位置t比k大,那么
t到n的部分不必再关心,反之,0到t部分不必再关心