LeetCode215.数组中的第K个最大元素
更新: 2/27/2026 字数: 0 字 时长: 0 分钟
很经典的topK的题了,题意不多描述。
法一:快速选择算法
思路
要求第
- 我们可以在
中随机选择一个基准元素 。 - 然后我们通过对数组进行操作交换,使得
的数在左边, 的数在右边,这样我们就能得到 在整个数组中的相对位置下标。
TIP
如果
- 假设我们当前得到的pivot下标为
,如果 ,则返回答案;如果 ,则我们需要在左边的范围去找;如果 ,则我们需要在右边的范围去找。
整个过程有点类似于二分答案,每一步操作都会减小问题的规模。
复杂度
第一次划分需要处理
为什么选择基准元素时需要随机选取?因为如果每次都取第一个的话,会导致划分是不平均的,在某些情况下会退化至
,故我们需要随机选取,保证期望的时间复杂度为 ,这里取中间应该也是可以的。
代码
参考代码如下:
cpp
class Solution {
int getIndex(vector<int>& nums, int l, int r) {
int i = l + rand() % (r - l + 1);
int tmp = nums[i];
// 将pivot与第一个交换,方便后续操作
swap(nums[l], nums[i]);
i = l + 1;
int j = r;
while(1) {
while(i <= j && nums[i] < tmp) i++;
while(i <= j && nums[j] > tmp) j--;
if (i >= j) break;
swap(nums[i], nums[j]);
i++,j--;
}
// 将pivot与得到的index交换,确定位置
swap(nums[l], nums[j]);
return j;
}
public:
int findKthLargest(vector<int>& nums, int k) {
srand(time(NULL));
int n = nums.size();
int l = 0, r = n - 1;
while(l <= r) {
int i = getIndex(nums, l, r);
if (i == n - k) return nums[i];
if (i > n - k) {
r = i - 1;
} else {
l = i + 1;
}
}
return 0;
}
};堆排序
TODO待填坑,堆排序的时间复杂度为
