快速选择
快速选择
-
快速排序的思想变形
-
每次只递归一个区间\(O(n)\)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N];
int quick_select(int l,int r,int k,int q[]) {
if(l >= r) return q[l];// l == r,返回谁都一样
int base = q[l + r >> 1],i = l - 1,j = r + 1;
while(i < j) {
do i ++;while(q[i] < base);
do j --;while(q[j] > base);
if(i < j) swap(q[i],q[j]);
}// 以上都是快排的模板
// j - l + 1 是当前区间的左半边长度,如果 k 在左半边,就继续在左半边递归找
if(j - l + 1 >= k) return quick_select(l,j,k,q);
// 否则 k 就在右半边,但是k要变成 k - (j - l + 1),把左半边的序号减去,变成新的 k
else return quick_select(j + 1,r,k - (j - l + 1),q);
}
int main() {
int n,k;
scanf("%d%d",&n,&k);
for(int i = 0;i < n; ++i) scanf("%d",&a[i]);
printf("%d",quick_select(0, n - 1, k, a));
return 0;
}