[路飞]_剑指 Offer 40. 最小的k个数

145 阅读1分钟

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

剑指 Offer 40. 最小的k个数

输入整数数组 arr ,找出其中最小的 k 个数。

例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

「示例1:」
输入:arr = [3,2,1], k = 2
​
输出:[1,2] 或者 [2,1]
「示例2:」
输入:arr = [0,1,2,1], k = 1
​
输出:[0]
「示例3:」
输入:arr = [3,2,1,7,56], k = 3
​
输出:[1,2,3] 或者 [3,2,1]
「示例4:」
输入:arr = [56,13,26,100,22,1], k = 1
​
输出:[1]
「示例5:」
输入:arr = [132451121175646], k = 2
​
输出:[11,12] 或者 [12,11]
「示例6:」
输入:arr = [1,6,4,8,12,45,17,5], k = 3
​
输出:[1,4,5,6]
提示:
  • 0 <= k <= arr.length <= 10000
  • 0 <= arr[i] <= 10000

解题思路

1. 由题意可知,这是一道求最值的题目,对于求最值的题目我们都可以使用堆来进行解题
2. 我们可以构建一个大顶堆
3. 通过循环测试用例给我们的数组,判断当前值是否小于于堆顶的元素或者堆里面的元素小于k的时候,就向堆里面添加该值
4. 最后返回堆内的元素即可

代码实现

/**
 * 剑指 Offer 40. 最小的k个数
 * @param {number[]} arr
 * @param {number} k
 * @return {number[]}
 */
class BigHeap {
  constructor(k) {
    this.arr = [];
    this.size = 0;
    this.max = k;
  }
  push(val) {
    this.arr.push(val);
    this.size++;
    if (this.size > 1) {
      let cur = this.size - 1,
        parent = (cur - 1) >> 1;
      while (cur > 0 && this.arr[cur] > this.arr[parent]) {
        [this.arr[cur], this.arr[parent]] = [this.arr[parent], this.arr[cur]];
        cur = parent;
        parent = (cur - 1) >> 1;
      }
    }
    if (this.size > this.max) this.pop();
  }
​
  pop() {
    this.arr[0] = this.arr.pop();
    this.size--;
    let cur = 0,
      childl = 1,
      childr = 2;
    while (
      (childl < this.size && this.arr[childl] > this.arr[cur]) ||
      (childr < this.size && this.arr[childr] > this.arr[cur])
    ) {
      if (childl < this.size && this.arr[childl] < this.arr[childr]) {
        [this.arr[childr], this.arr[cur]] = [this.arr[cur], this.arr[childr]];
        cur = childr;
      } else {
        [this.arr[childl], this.arr[cur]] = [this.arr[cur], this.arr[childl]];
        cur = childl;
      }
      childr = cur * 2 + 2;
      childl = cur * 2 + 1;
    }
  }
  top() {
    return this.arr[0];
  }
}
var getLeastNumbers = function (arr, k) {
  if (k === 0) return [];
​
  const heap = new BigHeap(k);
​
  for (let i = 0; i < arr.length; i++) {
    if (heap.size < k || arr[i] < heap.top()) heap.push(arr[i]);
  }
​
  return heap.arr;
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;