[路飞]leetcode-973.最接近原点的K个点

105 阅读1分钟

给定一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点,并且是一个整数 k ,返回离原点 (0,0) 最近的 k 个点。

这里,平面上两点之间的距离是 欧几里德距离( √(x1 - x2)2 + (y1 - y2)2 )。

你可以按 任何顺序 返回答案。除了点坐标的顺序之外,答案 确保 是 唯一 的。力扣原文

示例 1:

输入: points = [[1,3],[-2,2]], k = 1
输出: [[-2,2]]
解释:
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]

示例 2:

输入: points = [[3,3],[5,-1],[-2,4]], k = 2
输出: [[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)

解题:

 class Heap {
    constructor(cmp, max) {
      const defaultCmp = (a, b) => a > b;
      this.list = [];
      //默认大顶堆
      this.cmp = cmp || defaultCmp;
      this.max = max || null;
    }
    size() {
      return this.list.length;
    }
    top() {
      return this.list.length === 0 ? null : this.list[0];
    }
    push(val) {
      this.list.push(val);
      if (this.size() > 1) {
        this.bubbleUp(this.size() - 1);
      }
      if (this.max !== null && this.size() > this.max) this.pop();
    }
    pop() {
      if (!this.size()) {
        return null;
      } else if (this.size() === 1) {
        return this.list.pop();
      }
      const top = this.list[0];
      this.list[0] = this.list.pop();
      this.bubbleDown(0);
      return top;
    }
    //向上调整
    bubbleUp(idx) {
      while (idx) {
        let parentIdx = (idx - 1) >> 1;
        if (this.cmp(this.list[parentIdx], this.list[idx])) {
          this.swap(idx, parentIdx);
          idx = parentIdx;
        } else {
          break;
        }
      }
    }
    //向下调整
    bubbleDown() {
      let cur = 0,
        leftIdx = 1,
        rightIdx = 2,
        size = this.size();
      while (
        (leftIdx < size && this.cmp(this.list[cur], this.list[leftIdx])) ||
        (rightIdx < size && this.cmp(this.list[cur], this.list[rightIdx]))
      ) {
        if (
          rightIdx < size &&
          this.cmp(this.list[leftIdx], this.list[rightIdx])
        ) {
          this.swap(rightIdx, cur);
          cur = rightIdx;
        } else {
          this.swap(leftIdx, cur);
          cur = leftIdx;
        }
        (leftIdx = cur * 2 + 1), (rightIdx = cur * 2 + 2);
      }
    }
    // 交换
    swap(i, j) {
      [this.list[i], this.list[j]] = [this.list[j], this.list[i]];
    }
  }
var kClosest = function (points, k) {
    const heap=new Heap(
       
        (a,b)=>{
            const aVla=a[0]*a[0]+a[1]*a[1]
            const bVla=b[0]*b[0]+b[1]*b[1]
            return aVla<bVla
        },
        k
    )
    points.forEach(element => {
        heap.push(element)
    });
    return heap.list
};