这是一个典型的选择问题,这里我们采用分治算法 RandomizedSelect,其渐近运行时间为Θ(n)。这里我们与快排类似,对数组进行递归划分,但与快速排序不同的是,快速排序会递归处理划分的两边,而 RandomizedSelect 只处理划分的一边。
template<typename T>
int partitionArray(T arr[], int low, int high)
{
T pivot = arr[high];
int i = low - 1;
for(int j = low; j < high; ++j)
if(arr[j] <= pivot)
std::swap(arr[++i], arr[j]);
std::swap(arr[++i], arr[high]);
return i;
}
template<typename T>
int randomizedPartition(T arr[], int low, int high)
{
std::default_random_engine random(time(nullptr));
std::uniform_int_distribution<int> dis(low, high);
int i = dis(random);
std::swap(arr[i], arr[high]);
return partitionArray(arr, low, high);
}
template<typename T>
T randomizedSelect(T arr[], int low, int high, int i)
{
if(low == hig