[路飞] 48——leetcode -剑指 Offer 40. 最小的k个数

77 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

剑指 Offer 40. 最小的k个数

题目分析

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

思路讲解

我们可以维护⼀个⼩根堆⽤来给所有元素排序。排序后堆中的前K个元素就是我们需要的元素

示例

示例1:
输入: arr = [3,2,1], k = 2
输出: [1,2] 或者 [2,1]

示例2:
输入: arr = [0,1,2,1], k = 1
输出: [0]

代码

/**
 * @param {number[]} arr:数组arr
 * @param {number} k:找出其中最小的k个数
 * @return {number[]}
 */
var getLeastNumbers = function(arr, k) {
    let len = arr.length // 获取数组的长度
    let res = [] // 定义res,存储要返回的数组
    // 处理边界条件
    if (k === 0) return [] // k等于0,直接返回
    if (k === len) return arr // k等于数组长度,直接返回,要返回所有的数组
    // 把所有的数全放到小根堆中,每一次出堆,出堆的结果就是我们想要的,拿出来之后,就放到数组中
    buildHeap(arr)
    for (let i = 1; i <= k; i++) {
        res.push(arr[0])
        swap(arr, 0, len - i)
        heapAdjust(arr, 0, len - i)
    }
    return res
};
var buildHeap = function (arr) {
    let len = arr.length
    for (let i = Math.floor(len / 2); i >= 0; i--) {
        heapAdjust(arr, i, len)
    }
}
var swap = function (arr, i, child) {
    if (i === child) return
    arr[i] = arr[child] + arr[i]
    arr[child] = arr[i] - arr[child]
    arr[i] = arr[i] - arr[child]
}
var heapAdjust = function (arr, i, len) {
    let child = i * 2 + 1
    while (child < len) {
        if (child + 1 < len && arr[child] > arr[child + 1]) {
            child = child + 1
        }
        if (arr[child] < arr[i]) {
            swap(arr, i, child)
            i = child
            child = i * 2 + 1
        } else {
            break
        }
    }
}