📅  最后修改于: 2023-12-03 14:53:56.464000             🧑  作者: Mango
在程序开发中,我们常常需要查找数组中第k小或第k大的元素,当数组比较大时,一般使用快排等排序算法,但是当数组比较小或者需要多次查找时,使用排序算法反而不如直接查找效率高。本文将介绍一种时间复杂度为O(n)的算法,即小范围未排序数组中的第k个最小最大。
给定一个长度为n的未排序数组,以及一个整数k,找到该数组中第k小的元素和第k大的元素。
该问题可以分别解决第k小和第k大的问题,下面以第k小为例。
int findKthSmallest(int arr[], int n, int k)
{
if (n <= 0) {
return -1; // 数组为空
}
int pivotIndex = rand() % n;
int pivot = arr[pivotIndex];
int leftCount = 0;
int* leftArr = new int[n];
int* rightArr = new int[n];
for (int i = 0; i < n; i++) {
if (i == pivotIndex) continue;
if (arr[i] < pivot) {
leftArr[leftCount++] = arr[i];
} else {
rightArr[i-leftCount-1] = arr[i];
}
}
if (leftCount+1 == k) {
return pivot;
} else if (leftCount+1 > k) {
return findKthSmallest(leftArr, leftCount, k);
} else {
return findKthSmallest(rightArr, n-leftCount-1, k-leftCount-1);
}
}
由于每次递归时数组大小减半,故时间复杂度为O(n)。
小范围未排序数组中的第k个最小最大问题是算法面试经常考察的问题,掌握该算法可提高程序开发效率和通过面试的概率。