题目
输入n个整数,找出其中最大的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最大的4个数字是8,7,6,5。
面试通常会这样问:从1000000个数里面取前n大的数,或者从1000000个数里面取第n大的数
思路
求最小的K个数就建大顶堆,求最大的K个数就建小顶堆,然后之后遍历的元素不断和堆顶比较,重新调整堆
// partition方法
function GetLeastNumbers_Solution(input, k) {
// write code here
if (k > input.length || !k || !input || input.length === 0) {
return []
}
let index = partition(input, 0, input.length - 1)
while (index !== input.length - k) {
if (index < input.length - k) {
index = partition(input, index + 1, input.length - k)
} else {
index = partition(input.length - k, index - 1)
}
}
return input.slice(input.length - k, input.length)
}
function partition(arr, low, high) {
var pivot = arr[low]
while (low <= high) {
while (low <= high && arr[high] >= pivot) {
high--
}
[arr[low], arr[high]] = [arr[high], arr[low]]
while (low <= high && arr[low] <= pivot) {
low++
}
[arr[low], arr[high]] = [arr[high], arr[low]]
}
return low
}
// 取前n大的数
function GetLeastNumbers_Solution(input, k) {
if (!input || !input.length || !k || k > input.length) {
return []
}
let heap = input.slice(0, k)
makeMinHeap(heap)
for (let i = k; i < input.length; i++) {
if (input[i] > heap[0]) {
heap[0] = input[i]
heapAdjust(heap, 0, k)
}
}
return heap
}
function makeMinHeap(arr) {
let startIndex = Math.floor(arr.length / 2)
for (let i = startIndex; i >= 0; i--) {
heapAdjust(arr, i, arr.length)
}
}
function heapAdjust(arr, s, m) {
let temp = arr[s]
for (let i = s * 2 + 1; i < m; i = i * 2 + 1) {
if ((i + 1) < m && arr[i+1] < arr[i]) {
i++
}
if (temp < arr[i]) {
break
} else {
arr[s] = arr[i]
s = i
}
arr[s] = temp
}
}
let arr = [2, 1, 3, 4, 5, 6, 7, 8, 9]
console.log(GetLeastNumbers_Solution(arr, 4))
// 取第N大的数,可以维持一个n大小的小顶堆,然后取堆顶元素
function GetLeastNumbers_Solution(input, k) {
if (!input || !input.length || !k || k > input.length) {
return []
}
let heap = input.slice(0, k)
makeMinHeap(heap)
for (let i = k; i < input.length; i++) {
if (input[i] > heap[0]) {
heap[0] = input[i]
heapAdjust(heap, 0, k)
}
}
return heap[0]
}
function makeMinHeap(arr) {
let startIndex = Math.floor(arr.length / 2)
for (let i = startIndex; i >= 0; i--) {
heapAdjust(arr, i, arr.length)
}
}
function heapAdjust(arr, s, m) {
let temp = arr[s]
for (let i = s * 2 + 1; i < m; i = i * 2 + 1) {
if ((i + 1) < m && arr[i+1] < arr[i]) {
i++
}
if (temp < arr[i]) {
break
} else {
arr[s] = arr[i]
s = i
}
arr[s] = temp
}
}
let arr = [2, 1, 3, 4, 5, 6, 7, 8, 9]
console.log(GetLeastNumbers_Solution(arr, 4))