LintCode K个最近的点

题目

给定一些 points 和一个 origin,从 points 中找到 k 个离 origin 最近的点。
按照距离由小到大返回。如果两个点有相同距离,则按照x值来排序;若x值也相同,就再按照y值排序。

样例
给出 points = [[4,6],[4,7],[4,4],[2,5],[1,1]], origin = [0, 0], k = 3
返回 [[1,1],[2,5],[4,4]]

坐标点类

class Point {
    int x;
    int y;

    Point() {
        x = 0;
        y = 0;
    }

    Point(int a, int b) {
        x = a;
        y = b;
    }

    @Override
    public String toString() {
        return "[" + x + "," + y + "]";
    }
}

思路

  1. 计算距离^2,获得与点等长的数组,切距离与点的坐标一一对应。
  2. 循环k次,寻找k个最小距离,按照最小距离的下标,并记录最近距离点。
  3. 每次比较,都要交换距离调整和点在数组中的位置,防止丢失与重复。

代码

public static Point[] kClosest(Point[] points, Point origin, int k) {
        // Write your code here
        int[] distance = new int[points.length];
        //计算距离^2
        for (int i = 0; i < points.length; i++) {
            distance[i] = (points[i].x - origin.x) * (points[i].x - origin.x)
             + (points[i].y - origin.y) * (points[i].y - origin.y);
        }
        Point[] ps = new Point[k];
        //获取距离最近的k个坐标
        for (int i = 0; i < k; i++) {
            int min = distance[i];
            ps[i] = points[i];
            for (int j = i + 1; j < distance.length; j++) {
                if (min > distance[j]) {
                    min = distance[j];
                    //交换,调整对应距离值,防止重复
                    int t = distance[i];
                    distance[i] = distance[j];
                    distance[j] = t;
                    ps[i] = points[j];
                    //交换,调整对应坐标,防止重复
                    Point o = points[j];
                    points[j] = points[i];
                    points[i] = o;
                }

                if (min == distance[j]) {
                    if (points[i].x > points[j].x) {
                        ps[i] = points[j];
                        //交换,调整对应坐标,防止重复
                        Point o = points[j];
                        points[j] = points[i];
                        points[i] = o;
                    } else if (points[i].x == points[j].x) {
                        if (points[i].y > points[j].y) {
                            ps[i] = points[j];
                            //交换,调整对应坐标,防止重复
                            Point o = points[j];
                            points[j] = points[i];
                            points[i] = o;
                        }
                    }
                }
            }
        }
        return ps;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值