快速选择

快速选择

  • 快速排序的思想变形

  • 每次只递归一个区间\(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;
}
posted @ 2020-02-02 14:09  南风--  阅读(90)  评论(0编辑  收藏  举报