题目地址:
https://www.acwing.com/problem/content/4785/
给定一个长度为 n n n的整数数列 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,…,an,以及一个整数 k k k。请你计算并输出该数列从大到小排序后的第 k k k个数。
输入格式:
第一行包含两个整数
n
,
k
n,k
n,k。
第二行包含
n
n
n个整数
a
1
,
a
2
,
…
,
a
n
a_1,a_2,…,a_n
a1,a2,…,an。
输出格式:
一个整数,表示数列从大到小排序后的第
k
k
k个数。
数据范围:
前三个测试点满足
1
≤
n
≤
10
1≤n≤10
1≤n≤10。
所有测试点满足
1
≤
n
≤
1000
1≤n≤1000
1≤n≤1000,
1
≤
k
≤
n
1≤k≤n
1≤k≤n,
0
≤
a
i
≤
100
0≤a_i≤100
0≤ai≤100。
快速选择。代码如下:
#include <iostream>
using namespace std;
int n, k;
int a[1010];
int quick_select(int l, int r, int k) {
if (l >= r) return a[l];
int i = l, j = r, piv = a[l + r >> 1];
while (i <= j) {
while (a[i] < piv) i++;
while (piv < a[j]) j--;
if (i <= j) swap(a[i++], a[j--]);
}
if (k <= j) return quick_select(l, j, k);
if (k >= i) return quick_select(i, r, k);
return a[k];
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
printf("%d\n", quick_select(1, n, n - k + 1));
}
平均时间复杂度 O ( n ) O(n) O(n),空间 O ( log n ) O(\log n) O(logn)。