1. class Heap {
    2. constructor(arr = [], cmp = (a, b) => a < b) {
    3. this.arr = arr // 用数组实现堆
    4. this.cmp = cmp // 比较函数
    5. this.init()
    6. }
    7. init() {
    8. if (this.size() < 2) return
    9. for (let i = 0; i < this.size(); i++) {
    10. this.bubbleUp(i)
    11. }
    12. }
    13. size() {
    14. return this.arr.length
    15. }
    16. // 返回堆顶元素
    17. top() {
    18. if (this.size()) return null
    19. return this.arr[0]
    20. }
    21. push(val) {
    22. this.arr.push(val)
    23. this.bubbleUp(this.size() - 1)
    24. }
    25. pop() {
    26. if (!this.size()) return null;
    27. if (!this.size() === 1) return this.arr.pop()
    28. const top = this.arr[0]
    29. this.arr[0] = this.arr.pop()
    30. this.bubbleDown(0)
    31. return top
    32. }
    33. // 向上调整
    34. bubbleUp(index) {
    35. let i = index
    36. while (i) {
    37. // 找到父节点
    38. const parIntIndex = Math.floor((i - 1) / 2)
    39. // 如果符合不规则,则交换元素,继续向上调整
    40. if (this.cmp(this.arr[i], this.arr[parIntIndex])) {
    41. [this.arr[parIntIndex], this.arr[i]] = [this.arr[i], this.arr[parIntIndex]]
    42. i = parIntIndex
    43. } else {
    44. break
    45. }
    46. }
    47. }
    48. // 向下调整
    49. bubbleDown(index) {
    50. const lastIndex = this.size() - 1
    51. let i = index
    52. while (i < lastIndex) {
    53. let findIndex = i
    54. // 子左节点
    55. const leftIndex = i * 2 + 1
    56. // 子右节点
    57. const rightIndex = i * 2 + 2
    58. // 如果左节点不符合规则,则作为交换节点
    59. if (leftIndex <= lastIndex && this.cmp(this.arr[leftIndex], this.arr[findIndex])) {
    60. findIndex = leftIndex
    61. }
    62. // 如果右节点不符合规则,则作为交换节点
    63. if (rightIndex <= lastIndex && this.cmp(this.arr[rightIndex], this.arr[findIndex])) {
    64. findIndex = rightIndex
    65. }
    66. // 交换目标值
    67. if (findIndex > i) {
    68. [this.arr[findIndex], this.arr[i]] = [this.arr[i], this.arr[findIndex]]
    69. i = findIndex
    70. } else {
    71. break
    72. }
    73. }
    74. }
    75. }
    76. /**
    77. * @param {number[]} nums
    78. * @param {number} k
    79. * @return {number}
    80. */
    81. var findKthLargest = function (nums, k) {
    82. const heap = new Heap()
    83. // 维护一个k大小的最小堆
    84. for (let i = 0; i < nums.length; i++) {
    85. heap.push(nums[i])
    86. if (heap.size() > k) {
    87. heap.pop()
    88. }
    89. }
    90. return heap.pop()
    91. };