题目
- 输入n个整数,找出其中最大的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最大的4个数字是8,7,6,5。
- 面试通常会这样问:从1000000个数里面取前n大的数,或者从1000000个数里面取第n大的数
思路
-
维护小顶堆
-
求最小的K个数就建大顶堆,求最大的K个数就建小顶堆,然后之后遍历的元素不断和堆顶比较,重新调整堆
/**
* @param {number[]} arr
* @param {number} k
* @return {number[]}
*/
var getBigestNumbers = function (arr, k) {
if (arr.length <= k) return arr
const heap = new SmallHeap()
for (let i = 0; i < arr.length; i++) {
if (i <= k - 1) {
heap.insert(arr[i])
continue
}
heap.update(arr[i])
}
return heap.get()
}
function SmallHeap() {
this.heap = [null]
}
SmallHeap.prototype.update = function(x) {
if (x > this.heap[1]) {
this.heap[1] = x
this.heapify()
}
}
SmallHeap.prototype.insert = function(x) {
this.heap.push(x)
let index = this.heap.length - 1
while (Math.floor(index / 2) > 0 && this.heap[index] < this.heap[Math.floor(index / 2)]) {
swap(this.heap, Math.floor(index / 2), index)
index = Math.floor(index / 2)
}
}
SmallHeap.prototype.heapify = function() {
let i = 1
while (i < this.heap.length) {
let minIndex = i
if (2 * i < this.heap.length && this.heap[2 * i] < this.heap[minIndex]) {
minIndex = 2 * i
}
if (2 * i + 1 < this.heap.length && this.heap[2 * i + 1] < this.heap[minIndex]) {
minIndex = 2 * i + 1
}
if (minIndex === i) break
swap(this.heap, minIndex, i)
i = minIndex
}
}
SmallHeap.prototype.get = function() {
return this.heap.slice(1)
}
function swap(arr, i, j) {
const temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}