let findKthLargest = function(nums, k) { // 从 nums 中取出前 k 个数,构建一个小顶堆 let heap = [,], i = 0 while(i < k) { heap.push(nums[i++]) } buildHeap(heap, k) // 从 k 位开始遍历数组 for(let i = k; i < nums.length; i++) { if(heap[1] < nums[i]) { // 替换并堆化 heap[1] = nums[i] heapify(heap, k, 1) } } // 返回堆顶元素 return heap[1]};// 原地建堆,从后往前,自上而下式建小顶堆let buildHeap = (arr, k) => { if(k === 1) return // 从最后一个非叶子节点开始,自上而下式堆化 for(let i = Math.floor(k/2); i>=1 ; i--) { heapify(arr, k, i) }}// 堆化let heapify = (arr, k, i) => { // 自上而下式堆化 while(true) { let minIndex = i if(2*i <= k && arr[2*i] < arr[i]) { minIndex = 2*i } if(2*i+1 <= k && arr[2*i+1] < arr[minIndex]) { minIndex = 2*i+1 } if(minIndex !== i) { swap(arr, i, minIndex) i = minIndex } else { break } }}// 交换let swap = (arr, i , j) => { let temp = arr[i] arr[i] = arr[j] arr[j] = temp}
构建最小堆
/** * @param {number[]} nums * @param {number} k * @return {number} */class MinHeap { constructor() { this.heap = []; } getParentIndex(i) { return (i - 1) >> 1; // 二进制 } getLeftIndex(i) { return i * 2 + 1; } getRightIndex(i) { return i * 2 + 2; } shiftUp(index) { if (index === 0) { return; } const parentIndex = this.getParentIndex(index); if (this.heap[parentIndex] > this.heap[index]) { this.swap(parentIndex, index); this.shiftUp(parentIndex); } } swap(i1, i2) { const temp = this.heap[i1]; this.heap[i1] = this.heap[i2]; this.heap[i2] = temp; } insert(value) { this.heap.push(value); this.shiftUp(this.heap.length - 1); } pop() { this.heap[0] = this.heap.pop(); this.shiftDown(0); } shiftDown(index) { const leftIndex = this.getLeftIndex(index); const rightIndex = this.getRightIndex(index); if (this.heap[leftIndex] < this.heap[index]) { this.swap(leftIndex, index); this.shiftDown(leftIndex); } if (this.heap[rightIndex] < this.heap[index]) { this.swap(rightIndex, index); this.shiftDown(rightIndex); } } peek() { return this.heap[0]; } size() { return this.heap.length; }}// 大根堆排序let findKthLargest = function(nums, k) { let h = new MinHeap(); nums.forEach(c => { h.insert(c); while(h.size()>k){ h.pop() } }) return h.peek();};
堆排序
https://github.com/sisterAn/JavaScript-Algorithms/issues/60