acwing-786. 第k个数
给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。
输入格式
第一行包含两个整数 n 和 k。
第二行包含 n 个整数(所有整数均在 1~10^9 范围内),表示整数数列。
输出格式
输出一个整数,表示数列的第 k 小数。
数据范围
1≤n≤100000,
1≤k≤n
输入样例:
5 3
2 4 1 5 3
输出样例:
3
方法一:
借助快排中partition的思想,假设第一个数是要找的第k小的数,对待处理数据一轮partition过后,若这个数所在的位置处于数组的
- 第k个位置,输出该数,算法完成
- 若所在位置
- 若所在位置>k,则以该元素为pivot的左边部分的元素进行partition
若随机取pivot,平均时间复杂度为O(n)
这里代码懒得随机取了,AC
#include
int nums[1000010];
int findMid(int low, int high, int k) {
int pivot = nums[low], l = low, h = high;
while (low < high) {
while (low < high && nums[high] >= pivot) high--;
nums[low] = nums[high];
while (low < high && nums[low] <= pivot) low++;
nums[high] = nums[low];
}
if (low == k) return pivot;
else if (low < k) return findMid(low + 1, h, k);
else return findMid(l, low-1, k);
}
int main() {
int n, k, a, b;
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &(nums[i]));
}
printf("%d", findMid(1, n, k));
}