https://leetcode.com/problems/kth-largest-element-in-an-array/
给定一个数组,求它的第 k k k大元素(真实定义是从大到小排好序后位于第 k k k个的数,或者下标 k − 1 k-1 k−1的数)。
快速选择算法。代码如下:
class Solution {
public:
int findKthLargest(vector<int>& A, int k) {
int n = A.size();
k = n - k;
return quick_select(A, 0, n - 1, k);
}
int quick_select(vector<int>& A, int l, int r, int k) {
if (l >= r) return A[l];
int i = l, j = r, piv = A[l + (r - l >> 1)];
while (i <= j) {
while (A[i] < piv) i++;
while (A[j] > piv) j--;
if (i <= j) swap(A[i++], A[j--]);
}
if (k <= j) return quick_select(A, l, j, k);
if (k >= i) return quick_select(A, i, r, k);
return A[k];
}
};
平均时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。
算法正确性可以由快速排序的证明得到。具体可以参照:https://blog.csdn.net/qq_46105170/article/details/104085776。下证时间复杂度。对于时间复杂度,假设每次的分点出现的位置的概率符合均匀分布。有递推方程(其实就是花了 O ( n ) O(n) O(n)的时间以 1 n \frac{1}{n} n1的概率eliminate掉若干数字): T ( n ) = n + 1 n ( T ( n − 1 ) + T ( n − 2 ) + . . . + T ( 1 ) ) T(n)=n+\frac{1}{n}(T(n-1)+T(n-2)+...+T(1)) T(n)=n+n1(T(n−1)+T(n−2)+...+T(1))所以 n T ( n ) − n T ( n − 1 ) = 2 n − 1 T ( n ) − T ( n − 1 ) = 2 − 1 n nT(n)-nT(n-1)=2n-1\\T(n)-T(n-1)=2-\frac{1}{n} nT(n)−nT(n−1)=2n−1T(n)−T(n−1)=2−n1累加起来即得: T ( n ) = O ( n ) T(n)=O(n) T(n)=O(n)