数组中的第K个最大元素
LeetCode 215:给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
时间复杂度要求是O(n)。
int quickSelect(vector<int>& nums, int left, int right, int k) {
if (left == right) {
return nums[k];
}
int pivot = nums[left], i = left - 1, j = right + 1;
while (i < j) {
do { i++; } while (nums[i] < pivot);
do { j--; } while (nums[j] > pivot);
if (i < j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
if (k <= j) return quickSelect(nums, left, j, k);
else return quickSelect(nums, j + 1, right, k);
}
int findKthLargest(vector<int>& nums, int k) {
return quickSelect(nums, 0, nums.size() - 1, nums.size() - k);
}
-
quickSelect
函数是快速选择算法的主要实现部分。这个函数接受一个整数数组nums
,一个左边界left
和一个右边界right
,以及一个目标索引k
。它使用递归来实现快速选择。- 如果
left
等于right
,那么数组中只有一个元素,直接返回这个元素即可。 - 否则,选择数组中间的元素作为枢轴(pivot)。然后,通过比较枢轴元素和数组中其他元素的大小关系,将数组分为两部分:小于枢轴的元素和大于枢轴的元素。
- 根据目标索引
k
与当前枢轴位置的关系,递归调用quickSelect
函数,分别在小于枢轴的部分和大于枢轴的部分进行选择。 - 最终,递归调用会返回目标索引
k
对应的元素。
- 如果
-
findKthLargest
函数是调用quickSelect
函数的地方,它使用了一个技巧来减少递归深度。这个函数接受一个整数数组nums
和一个目标索引k
,它调用quickSelect
函数时,将左边界设置为0,右边界设置为数组长度减1,目标索引设置为数组长度减k。这样,只需要对数组进行一次递归调用就可以找到第k大的元素。