题目描述
给定一个长度为n的整数数列,以及一个整数k,请用快速选择算法求出数列从小到大排序后的第k个数。
输入样例
5 3
2 4 1 5 3
输出样例
3
快速排序
思想还是快速排序, 只是因为只需要求第 k 个数, 因此在递归的对两个子序列进行快速排序的时候, 只需要判断一下第 k 个数在左边还是右边的序列中, 具体判断左边的子序列长度 $j - l + 1$ 是否大于等于 $k$
时间复杂度
$O(n)$
C++ 代码
#include <iostream>
using namespace std;
const int N = 100010;
int n, k;
int q[N];
int qsort(int *q, int l, int r, int k) {
if (l >= r) return q[l];
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j) {
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
if (j - l + 1 >= k) return qsort(q, l, j, k);
else return qsort(q, j + 1, r, k - (j - l + 1));
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
cout << qsort(q, 0, n - 1, k) << endl;
return 0;
}