数组中的第 K 个最大元素 问题
方法一:排序法
最直接的方法是先对数组进行排序,然后取第 K 个最大的元素。这种方法的时间复杂度为 O(n log n)。
int findKthLargest(vector<int>& nums, int k) {
std::sort(nums.begin(), nums.end(), greater<int>());
return nums[k - 1];
}
方法二:使用最小堆
可以利用最小堆(Min-Heap)来实现,这种方法的时间复杂度为 O(n log k)。具体步骤如下:
步骤:
- 创建一个大小为 K 的最小堆。
- 遍历数组,将元素依次插入堆中。如果堆的大小超过 K,则弹出堆顶元素。
- 遍历结束后,堆顶元素即为第 K 个最大元素。
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> pq;
for (int i = 0; i < nums.size(); i++) {
pq.push(nums[i]);
if (pq.size() > k) {
pq.pop();
}
}
return pq.top();
}
方法三:快速选择算法(Quickselect)
快速选择算法是快速排序(Quicksort)的一个变种,时间复杂度为 O(n) 平均时间复杂度,但在最坏情况下为 O(n²)。
步骤:
- 选择一个枢轴元素。
- 通过一次划分操作将数组分为两部分:左边部分小于枢轴,右边部分大于枢轴。
- 判断第 K 个最大元素位于哪一部分,递归处理。
void quick_select(vector<int>& nums, int left, int right, int k) {
if (left >= right) return;
int l = left, r = right;
int pivot = nums[left + (right - left) / 2];
while (l <= r) {
while (l <= r && nums[l] > pivot) ++l;
while (l <= r && nums[r] < pivot) --r;
if (l <= r) {
swap(nums[l], nums[r]);
++l;
--r;
}
}
if (k <= r) quick_select(nums, left, r, k);
if (k >= l) quick_select(nums, l, right, k);
}
int findKthLargest(vector<int>& nums, int k) {
quick_select(nums, 0, nums.size() - 1, k - 1);
return nums[k - 1];
}