剑指OFFER----40-2最大的K个数(最小的K个数的变种)(js实现)

题目

输入n个整数,找出其中最大的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最大的4个数字是8,7,6,5。

面试通常会这样问:从1000000个数里面取前n大的数,或者从1000000个数里面取第n大的数


思路

  1. partition法
  2. 维护小顶堆

求最小的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))

你可能感兴趣的:(剑指OFFER,剑指OFFER(JS版))