572 字
3 分钟
数组中的第K个最大元素

题目描述
给定整数数组 nums
和整数 k
,请返回数组中第 **k**
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
你必须设计并实现时间复杂度为 O(n)
的算法解决此问题。
解题思路
- 快速选择算法:
- 随机化分区:选取随机pivot将数组分为大于/小于pivot的两部分
- 分治策略:根据pivot位置与k的关系,递归处理左或右子数组
- 终止条件:pivot正好是第k大元素时返回
- 堆排序优化:
- 构建大小为k的最小堆
- 遍历数组,维护堆顶为当前第k大元素
- 最终堆顶即为结果
关键洞察
- 快速选择本质:快速排序的变种,但只需处理目标所在分区
- 随机化避免最坏:随机选择pivot防止有序数组的O(n²)退化
- 堆的适用场景:海量数据流场景(空间效率高)
- 索引转换:第k大元素下标 =
n - k
(升序排序)
复杂度分析
方法 | 时间复杂度 | 空间复杂度 |
---|---|---|
快速选择 | 平均O(n),最坏O(n²) | 递归栈O(log n) |
堆方法 | O(n log k) | O(k) |
排序法 | O(n log n) | O(1) |
最优选择:
- 常规场景:快速选择(平均线性时间)
- 内存受限:堆方法(仅需O(k)空间)
- 巨量数据流:堆方法是唯一可行解
代码实现
/** * @link {https://leetcode.cn/problems/kth-largest-element-in-an-array} * @param {number[]} nums * @param {number} k * @return {number} */var findKthLargest = function (nums, k) { const quickSelect = (num, l, r, k) => { if (l === r) return num[k];
const x = num[l]; let i = l - 1, j = r + 1;
while (i < j) { do i++; while (num[i] < x); do j--; while (num[j] > x); if (i < j) { [num[i], num[j]] = [num[j], num[i]] } }
if (k <= j) { return quickSelect(num, l, j, k); } else { return quickSelect(num, j + 1, r, k); } }
const n = nums.length; return quickSelect(nums, 0, n - 1, n - k);};