目录
问题描述
"线性时间选择"通常指的是在一组元素中以线性时间复杂度找到第k小(或第k大)的元素。给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素。(这里给定的线性集是无序的)。(如果将这个线性集先排好序,则排在第k个位置的元素即为要找的元素)
解题思路
使用类似于快速选择算法的方法,它基于快速排序算法的思想。
快速选择算法的基本思想是选择一个枢纽元素(pivot),然后根据枢纽元素的值将数组分成两部分,一部分包含比枢纽元素小的元素,另一部分包含比枢纽元素大的元素。然后根据枢纽元素的位置,决定继续在哪一部分进行查找,从而将问题规模减半。通过不断地划分和选择,最终可以在线性时间内找到第k小(或第k大)的元素。
核心代码
int Partition(int a[], int left, int right)
{
int i = left, j = r + 1;
int x = a[i];
while (true)
{
while (a[++i] < x && i <= right);
while (a[--j] > x);
if (i >= j)
break;
swap(a[i] = a[j]);
}
a[left] = a[j];
a[j] = x;
return j;
}
int select(int a[], int left, int right, int k)
{
if (left == right)
return a[left];
int i = Partition(a, left, right);
int j = i - left + 1;
if (k <= j)
return select(a, left, i, k);
else
return select(a, i + 1, right, k - j);
}