快速选择算法
快速选择算法
快速选择算法基于快速排序算法,时间复杂度由\(O(nlogn)\)降到\(O(n)\)
思想是这样的,快速选择不需要所有的数据,只需要知道这个数排在第几位
而快速排序算法刚好可以满足这个要求,因为快速选择算法每次都将整个区间一分为二,每次对比可以知道要求的数在哪个区间,然后选择对应的区间进行递归即可。
时间复杂度之所以降低,就是因为快速选择算法不需要递归两边。
#include <iostream>
using namespace std;
const int maxn = 1e5 + 10;
int q[maxn], n, m;
int solve(int l, int r, int k)
{
if (l == r)
return q[l];//保证了k一直在[l,r]中,区间里只有一个数的时候说明找到了答案
int tmp = q[l + r >> 1];
int i = l - 1, j = r + 1;
while (i < j) {
while (q[++i] < tmp);
while (q[--j] > tmp);
if (i < j)
swap(q[i], q[j]);
}
int sl = j - l + 1;//求出区间的长度,之所以用j,是因为这个是由下面如何递归决定的。递归的是solve(l,j,k),说明区间长度就是j-l+1。如果换成i,就必须用递归区间为i的方式
if (k <= sl)
return solve(l, j, k);
else
return solve(j + 1, r, k - sl);
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> q[i];
cout << solve(0, n - 1, m);
return 0;
}