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过后,若这个数所在的位置处于数组的

  1. 第k个位置,输出该数,算法完成
  2. 若所在位置
  3. 若所在位置>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));
}