1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| function findKthLargest(nums: number[], k: number): number { const target = nums.length - k;
function partition(lo: number, hi: number): number { const rand = lo + Math.floor(Math.random() * (hi - lo + 1)); [nums[rand], nums[hi]] = [nums[hi], nums[rand]]; const pivot = nums[hi]; let i = lo; for (let j = lo; j < hi; j++) { if (nums[j] < pivot) { [nums[i], nums[j]] = [nums[j], nums[i]]; i++; } } [nums[i], nums[hi]] = [nums[hi], nums[i]]; return i; }
let lo = 0; let hi = nums.length - 1; while (true) { const p = partition(lo, hi); if (p === target) return nums[p]; if (p < target) lo = p + 1; else hi = p - 1; } }
class MinHeap { private h: number[] = []; get size() { return this.h.length; } peek() { return this.h[0]; } push(v: number) { const h = this.h; h.push(v); let i = h.length - 1; while (i > 0) { const p = (i - 1) >> 1; if (h[p] <= h[i]) break; [h[p], h[i]] = [h[i], h[p]]; i = p; } } pop() { const h = this.h; const top = h[0]; const last = h.pop()!; if (h.length) { h[0] = last; let i = 0; while (true) { const l = 2 * i + 1; const r = 2 * i + 2; let s = i; if (l < h.length && h[l] < h[s]) s = l; if (r < h.length && h[r] < h[s]) s = r; if (s === i) break; [h[s], h[i]] = [h[i], h[s]]; i = s; } } return top; } }
function topKKthLargest(nums: number[], k: number): number { const heap = new MinHeap(); for (const x of nums) { if (heap.size < k) heap.push(x); else if (x > heap.peek()) { heap.pop(); heap.push(x); } } return heap.peek(); }
console.log(findKthLargest([3, 2, 1, 5, 6, 4], 2)); console.log(topKKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4));
|