题目
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4], k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
思路:快速选择
使用快速排序的划分思想。
function findKthLargest(nums: number[], k: number): number {
return quickSelect(nums, 0, nums.length - 1, k);
}
function quickSelect(nums: number[], left: number, right: number, k: number): number {
const pivotIndex = partition(nums, left, right);
if (pivotIndex === k - 1) {
// 如果基准元素的位置正好是第K个最大元素的位置,则返回基准元素的值
return nums[pivotIndex];
} else if (pivotIndex > k - 1) {
// 如果基准元素的位置大于第K个最大元素的位置,则在左侧子数组中继续递归查找
return quickSelect(nums, left, pivotIndex - 1, k);
} else {
// 如果基准元素的位置小于第K个最大元素的位置,则在右侧子数组中继续递归查找
return quickSelect(nums, pivotIndex + 1, right, k);
}
}
function partition(nums: number[], left: number, right: number): number {
const pivot = nums[right]; // 选择数组最后一个元素作为基准元素
let i = left;
for (let j = left; j < right; j++) {
if (nums[j] >= pivot) {
// 如果当前元素大于等于基准元素,则将其交换到左侧(较大元素的一侧)
swap(nums, i, j);
i++;
}
}
swap(nums, i, right); // 将基准元素放置到正确的位置上
return i; // 返回基准元素的位置
}
function swap(nums: number[], i: number, j: number): void {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
参考:
- 四种思路分析 www.cnblogs.com/dsj2016/p/5…
- 堆排序 zhuanlan.zhihu.com/p/571443103
- 快速选择的实现 leetcode.com/problems/kt…