[前端]_一起刷leetcode 面试题 17.14. 最小K个数

117 阅读2分钟

大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。

题目

面试题 17.14. 最小K个数

难度中等173收藏分享切换为英文接收动态反馈

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

示例:

输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]

提示:

  • 0 <= len(arr) <= 100000
  • 0 <= k <= min(100000, len(arr))

思路

这道题目之前给大家讲过最快的做法 -- 快排。今天给大家讲一下堆排序的做法。

  1. 由于我们要存储最小的k的数量,所以我们可以建立一个存储k的大顶堆;
  2. 一轮遍历,往堆里不断添加元素,如果数量超过了k,就移除堆顶的元素;
  3. 遍历完成后,这时候我们已经找到了最小的k个元素,然后把他们依次存放到结果数组中即可;
  4. 这样子的话是可以达到省空间的效果,当然我们也可以建立一个小顶堆,一个个取出元素,取k次即可。

实现

小顶堆 省时间

/**
 * @param {number[]} arr
 * @param {number} k
 * @return {number[]}
 */
var smallestK = function(arr, k) {
    if (k === 0) return [];
    
    const minHeap = new MinPriorityQueue();

    for (let i = 0; i < arr.length; i++) {
        minHeap.enqueue(arr[i]);
    }

    let result = [];
    while (k > 0) {
        result.push(minHeap.dequeue().element);
        k--;
    }

    return result;
};

大顶堆 省空间

/**
 * @param {number[]} arr
 * @param {number} k
 * @return {number[]}
 */
var smallestK = function(arr, k) {
    if (k === 0) return [];
    
    const maxHeap = new MaxPriorityQueue();

    for (let i = 0; i < arr.length; i++) {
        maxHeap.enqueue(arr[i]);

        if (maxHeap.size() > k) {
            maxHeap.dequeue();
        }
    }

    let result = [];
    while (!maxHeap.isEmpty()) {
        result.unshift(maxHeap.dequeue().element);
    }

    return result;
};

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。