思路
求第k小的数,第一时间就能想到和排序有关,但这个数据量用冒泡排序什么的肯定会很糟糕,所以用到了快速排序
在快速排序时,我们先选取一个基准值,然后把数组中所有比基准值小的数放到基准值左边,比基准值大的数放到基准值右边,等于基准值的数任意放在哪一边。
每一次完成这样的操作以后,我们根据k和基准值的大小关系,选取左区间或右区间递归,直到区间里只剩一个数,那就是我们要的第k小数
代码
#include <iostream> using namespace std; int num[5000005]; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x * f; } int deal(int left, int right, int k) { //如果left和right相等,说明只剩第k小的数 if (left == right)return num[k]; int lPtr = left; int rPtr = right; //选区间中间的值为基准值进行快速排序 int pivot = num[(left + right) >> 1]; while (lPtr <= rPtr) { while (num[lPtr] < pivot)lPtr++; while (num[rPtr] > pivot)rPtr--; if (lPtr <= rPtr) { swap(num[lPtr], num[rPtr]); lPtr++; rPtr--; } } //运行完上面的循环以后rPtr在lPtr的左边 //根据k的位置选择区间递归 if (k <= rPtr)return deal(left, rPtr, k); return deal(lPtr, right, k); } int main() { int T; //数据组数 T = read(); int n; //数列长度 int k; //求第k小的数 while (T-- > 0) { n = read(); k = read(); for (int i = 0; i < n; ++i) { num[i] = read(); } cout << deal(0, n, k) << endl; } }