703. 数据流中的第 K 大元素 设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
链接
Tips 求TopK的问题可以用大堆根或者小堆根来解决问题
最小堆
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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 class KthLargest { k : number = -1 ; heap = new minHeap (); constructor (k: number , nums: number [] ) { this .k = k; for (const x of nums) { this .add (x); } } add (val : number ): number { this .heap .offer (val) if (this .heap .size () > this .k ) { this .heap .poll () } console .log (this .heap .data ) return this .heap .peek () } } class minHeap { data : number [] = []; constructor (data = [] ) { this .data = data; this .heapify (); } comparator (a : number , b : number ): number { return a - b; } heapify ( ) { if (this .size () < 2 ) return ; for (let i = 1 ; i < this .size (); i++) { this .bubbleUp (i); } console .log (this .data ) } peek ( ) { if (this .size () === 0 ) return null return this .data [0 ] } offer (value ) { this .data .push (value) this .bubbleUp (this .size () - 1 ) } poll ( ) { if (this .size () === 0 ) { return null } const result = this .data [0 ] const last = this .data .pop () if (this .size () !== 0 ) { this .data [0 ] = last this .bubbleDown (0 ) } return result } swap (index1: number , index2: number ) { [this .data [index1], this .data [index2]] = [this .data [index2], this .data [index1]] } bubbleUp (index: number ) { while (index > 0 ) { const parentIndex = (index - 1 ) >> 1 if (this .comparator (this .data [index], this .data [parentIndex]) < 0 ) { this .swap (index, parentIndex) index = parentIndex } else { break } } } bubbleDown (index: number ) { const lastIndex = this .size () - 1 while (true ) { const leftIndex = index * 2 + 1 const rightIndex = index * 2 + 2 let findIndex = index if (leftIndex <= lastIndex && this .comparator (this .data [leftIndex], this .data [findIndex]) < 0 ) { findIndex = leftIndex } if (rightIndex <= lastIndex && this .comparator (this .data [rightIndex], this .data [findIndex]) < 0 ) { findIndex = rightIndex } if (index !== findIndex) { this .swap (index, findIndex) index = findIndex } else { break } } } size ( ) { return this .data .length } }