前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【一天一大 lee】最接近原点的 K 个点 (难度:中等) - Day20201109

【一天一大 lee】最接近原点的 K 个点 (难度:中等) - Day20201109

作者头像
前端小书童
发布2020-11-11 14:19:28
9540
发布2020-11-11 14:19:28
举报
文章被收录于专栏:前端小书童

题目:

我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。

(这里,平面上两点之间的距离是欧几里德距离。)

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

示例:

  1. 示例1:
代码语言:javascript
复制
输入: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]]。
  1. 示例2:
代码语言:javascript
复制
输入:points = [[3,3],[5,-1],[-2,4]], K = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)

提示:

  • 1 <= K <= points.length <= 10000
  • -10000 < points[i][0] < 10000
  • -10000 < points[i][1] < 10000

抛砖引玉

思路:

points中存放的是x、y轴的坐标,距离为z:

z^2 = x^2+y^2

求前k个距离最小的点,即前k小的z

遍历求每个位置points中对应的z的大小并且排序,返回前k个元素

都忘记勾股定理还有名字叫"欧几里德定理"...

抛砖引玉

代码语言:javascript
复制
/**
 * @param {number[][]} points
 * @param {number} K
 * @return {number[][]}
 */
var kClosest = function(points, K) {
  const newPoints = points.sort((a,b) => Math.sqrt(a[0]*a[0] + a[1]*a[1]) - Math.sqrt(b[0]*b[0] + b[1]*b[1]))
  return newPoints.substr(0,K)
};

快速排序

看了题解才发现本题考查的是排序,上面用api完成就有点流氓了...

找出数组中对前K小的元素排序:

  • 先从数列中取出一个数作为基准数points[left]
  • 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  • 如果左边有k个元素则结束排序
    • 多于K则left到K之间还存在未替换出的非前K小元素
    • 少于K则还有前K小元素未替换到前K的位置
代码语言:javascript
复制
var kClosest = function (points, K) {
  if (points.length <= K) return points;
  // 快速排序
  quickSelect(0, points.length - 1, K);

  // 传入左右边界假设分别为最小最大值,从左右边界遍历数组,遇到小于有边界的
  function quickSelect(left, right, K) {
    let z = sqrt(points[left]),  // 校验的点
        l = left,                
        r = right;
    while (l <= r) {
      // 左侧小于基准
      if (sqrt(points[l]) <= z) {
        l++;
        continue;
      }
      // 右侧大于基准
      if (sqrt(points[r]) > z) {
        r--;
        continue;
      }
      // 不满足上面情况,交互指针上位置,继续比较
      [points[l], points[r]] = [points[r], points[l]];
      l++;
      r--;
    }
    // 上面循环的终止条件是l指针越界、此时r上存在的元素小于基准,则前r小元素包括r指针上的元素
    [points[left], points[r]] = [points[r], points[left]];
    if (r == K) {
      return;
    } else if (r < K) {
      quickSelect(r + 1, right, K);
    } else {
      quickSelect(left, r - 1, K);
    }
  }
  // 到[0,0]的距离
  function sqrt([x,y]) {
    return Math.sqrt(x*x + y*y)
  }

  return points.slice(0, K);
};
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小书童 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目:
    • 示例:
      • 提示:
      • 抛砖引玉
        • 快速排序
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档