记录一下求解数组中的第K个最大元素。实际上,题解是一个快速排序的模板。快排还可以用来求解数组中的前K大(小)的元素。
class Solution {
public:
// 随机打乱数组中的元素
void shuffle(vector<int>& nums) {
size_t len = nums.size();
srand( (int)time(0) );
for (int i = 0; i < len; i++) {
int index_tmp = i + rand() % (len - i);
swap(nums[i], nums[index_tmp]);
}
}
// 划分元素
int partition(vector<int>& nums, int low, int hi) {
if ( low == hi ) return low;
int tmp = nums[low];
while ( low < hi ) {
// 从数组的右端向左端寻找比nums[low]小的元素,然后填充low的位置
while (low < hi && nums[hi] >= nums[low])
hi--;
nums[low] = nums[hi];
// 用下标low从数组的左端向右寻找比tmp大的元素,然后填充hi的位置
while ( low < hi && tmp > nums[low] )
low++;
nums[hi] = nums[low];
}
nums[low] = tmp;
return low;
}
int findKthLargest(vector<int>& nums, int k) {
// 打乱数组元素
shuffle(nums);
// 由于此快排是按照元素升序排列的,所以原数组中的第k大元素在排序后数组的n-k位置;
k = nums.size() - k;
int low = 0;
int hi = nums.size() - 1;
while ( low <= hi ) {
int p = partition(nums, low, hi);
if ( p > k ) // 第k大的元素在nums[0...p-1]
hi = p-1;
else if ( p < k) // 第k大的元素在nums[p+1...hi]
low = p + 1;
else
return nums[p];
}
return -1;
}
};