Original link: leetcode-cn.com/problems/zu…

Answer:

  1. This problem can be solved using a heap, which takes advantage of the heap’s ability to quickly insert and retrieve elements and always sort them as required.
  2. Use JavaScript to implement a binary heap, and the array elements into the heap, and then pull k elements in turn.
/ * * *@param {number[]} arr
 * @param {number} k
 * @return {number[]}* /
var getLeastNumbers = function(arr, k) {
  let result = []; // Store the result
  let heap = new BinaryHeap((a, b) = > a - b); // Create a heap with the elements sorted from smallest to largest

  // Insert all the array elements into the heap
  for (let i = 0; i < arr.length; i++) {
    heap.insert(arr[i]);
  }

  // Retrieve k elements from the heap in order
  for (let j = 0; j < k; j++) {
    result.push(heap.deleteHead());
  }

  return result;
};

class BinaryHeap {
  constructor(compare) {
    this.data = []; // Use arrays to store the heap
    this.compare = compare; // The sorting function of the heap elements
  }

  // Insert elements into the heap
  insert(value) {
    this.insertAt(this.data.length, value);
  }

  // Insert the element into the index position
  insertAt(index, value) {
    // Insert the element at the specified position
    this.data[index] = value;
    let fatherIndex = index;
    // Compare the current node with its parent and swap them if the current node is smaller
    Math.floor((index-1) / 2) is the index of the parent node in the array
    while (
      index > 0 &&
      // Compare sizes using the passed contrast function
      this.compare(
        value,
        this.data[(fatherIndex = Math.floor((index - 1) / 2)))"0
    ) {
      // Move the parent node to the current location
      this.data[index] = this.data[fatherIndex];
      // Move the inserted value to the parent node
      this.data[fatherIndex] = value;
      // Update index to parent index, continue the next loopindex = fatherIndex; }}// Delete the largest node
  deleteHead() {
    return this.delete(0);
  }

  // Remove the element at the specified position
  delete(index) {
    // If the heap is empty, no deletion is performed
    if (this.data.length === 0) {
      return;
    }

    let value = this.data[index]; // Cache of elements to be deleted
    let parent = index; // Start with the current element and sort down the heap

    // The parent node is replaced with the larger child node after the compare method
    while (parent < this.data.length) {
      let left = parent * 2 + 1; // Index of the left child node
      let right = parent * 2 + 2; // Index of the right child node

      // There is no left child node, indicating that the current node is the last node
      if (left >= this.data.length) {
        break;
      }

      // If there is no right child node, the left child node can be brought forward to the parent node
      // The left child is the last node
      if (right >= this.data.length) {
        this.data[parent] = this.data[left];
        parent = left;
        break;
      }

      // Use the compare method to compare the size of the left and right child nodes
      if (this.compare(this.data[left], this.data[right]) < 0) {
        // Since the deleted node is already saved, you only need to copy the child node to the current parent node
        this.data[parent] = this.data[left];
        // Move the parent pointer to the child node for the next collation
        parent = left;
      } else {
        this.data[parent] = this.data[right]; parent = right; }}// Check whether the last empty space is the last leaf node
    if (parent < this.data.length - 1) {
      // If you have not collated to the leaf node, continue collating
      this.insertAt(parent, this.data.pop());
    } else {
      // When the collation is complete, the last node is more than one element
      this.data.pop();
    }

    // Returns the deleted element
    returnvalue; }}Copy the code