Heap / Priority Queue

Heap

Signal

Top K / K largest / K closest / K most frequent

Template

Keep a size-K heap; push/pop is O(log K).

Worked example (1)

#10

Heap

Heap

Given points on a plane and a number k, return the k points closest to the origin.

class MinHeap<T> {
  private items: T[] = [];
  constructor(private compare: (a: T, b: T) => number) {}
  get size(): number { return this.items.length; }
  push(item: T): void {
    this.items.push(item);
    let i = this.items.length - 1;
    while (i > 0) {
      const parent = (i - 1) >> 1;
      if (this.compare(this.items[parent], this.items[i]) <= 0) break;
      [this.items[parent], this.items[i]] = [this.items[i], this.items[parent]];
      i = parent;
    }
  }
  pop(): T | undefined {
    const top = this.items[0];
    const last = this.items.pop();
    if (this.items.length && last !== undefined) {
      this.items[0] = last;
      let i = 0;
      for (;;) {
        const left = 2 * i + 1, right = left + 1;
        let best = i;
        if (left < this.items.length && this.compare(this.items[left], this.items[best]) < 0) best = left;
        if (right < this.items.length && this.compare(this.items[right], this.items[best]) < 0) best = right;
        if (best === i) break;
        [this.items[i], this.items[best]] = [this.items[best], this.items[i]];
        i = best;
      }
    }
    return top;
  }
}

function kClosest(points: number[][], k: number): number[][] {
  const dist = (p: number[]): number => p[0] * p[0] + p[1] * p[1];
  const heap = new MinHeap<number[]>((a, b) => dist(a) - dist(b));
  for (const p of points) heap.push(p);
  const res: number[][] = [];
  for (let i = 0; i < k && heap.size > 0; i++) res.push(heap.pop()!);
  return res;
}
Insight

No need to sort all points — the heap surfaces just the k you want. Neither language ships a heap, so bring your own.