问题描述:
给定一个未排序的整数数组,找到其中第 k 大的元素。注意,你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
举个例子:
如果给定数组是 [3,2,1,5,6,4],k 是 2,那么第 2 大的元素是 5。
解决方案
快速选择(Quickselect)算法
function findKthLargest(nums, k) {
// 定义一个辅助函数用于快速选择
function quickSelect(arr, left, right, k) {
if (left === right) return arr[left];
// 使用随机选取一个 pivot 元素
let pivotIndex = Math.floor(Math.random() * (right - left + 1)) + left;
pivotIndex = partition(arr, left, right, pivotIndex);
if (k === pivotIndex + 1) {
return arr[pivotIndex];
} else if (k < pivotIndex + 1) {
return quickSelect(arr, left, pivotIndex - 1, k);
} else {
return quickSelect(arr, pivotIndex + 1, right, k);
}
}
// 辅助函数:根据 pivot 将数组划分为两部分
function partition(arr, left, right, pivotIndex) {
let pivotValue = arr[pivotIndex];
swap(arr, pivotIndex, right);
let storeIndex = left;
for (let i = left; i < right; i++) {
if (arr[i] > pivotValue) {
swap(arr, i, storeIndex);
storeIndex++;
}
}
swap(arr, storeIndex, right);
return storeIndex;
}
// 辅助函数:交换数组中的两个元素
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 调用快速选择算法找到第 k 大的元素
return quickSelect(nums, 0, nums.length - 1, k);
}
测试
// 测试
let nums = [3,2,1,5,6,4];
let k = 2;
console.log(findKthLargest(nums, k)); // 输出: 5
算法复杂度
这个算法的平均时间复杂度为 O(n),其中 n 是数组的长度。