42 lines
1.1 KiB
JavaScript
42 lines
1.1 KiB
JavaScript
/**
|
||
* @param {number[]} nums
|
||
* @param {number} k
|
||
* @return {number}
|
||
*/
|
||
const findKthLargest = function (nums, k) {
|
||
// 将数组的前k个元素作为堆,然后将其堆化
|
||
const heap = nums.slice(0, k);
|
||
// 从最后一个非叶子节点遍历,自底向上下沉堆化
|
||
for (let i = Math.floor(k / 2 - 1); i >= 0; i--) {
|
||
siftDown(heap, i, k);
|
||
}
|
||
// 处理剩余元素
|
||
for (let i = k; i < nums.length; i++) {
|
||
// 如果剩余元素大于堆顶元素,替换然后下沉维护堆
|
||
if (nums[i] > heap[0]) {
|
||
heap[0] = nums[i];
|
||
siftDown(heap, 0, k);
|
||
}
|
||
}
|
||
|
||
return heap[0];
|
||
};
|
||
|
||
// 下沉函数(维护堆性质)
|
||
function siftDown(heap, start, heapSize) {
|
||
let cur = start;
|
||
while (true) {
|
||
const left = 2 * cur + 1;
|
||
const right = 2 * cur + 2;
|
||
let smallest = cur;
|
||
|
||
if (left < heapSize && heap[left] < heap[smallest]) smallest = left;
|
||
if (right < heapSize && heap[right] < heap[smallest]) smallest = right;
|
||
|
||
if (smallest === cur) break;
|
||
|
||
[heap[cur], heap[smallest]] = [heap[smallest], heap[cur]];
|
||
cur = smallest;
|
||
}
|
||
}
|