lintcode612 - K Closest Points - medium
Given some points and a point origin in two dimensional space, find k points out of the some points which are nearest to origin.
Return these points sorted by distance, if they are same with distance, sorted by x-axis, otherwise sorted by y-axis.
Example
Given points = [[4,6],[4,7],[4,4],[2,5],[1,1]], origin = [0, 0], k = 3
return [[1,1],[2,5],[4,4]]
大根堆。O(nlogk)时间复杂度,O(k)空间复杂度。
和largest k number思路很像。只是这次要选出最近的一批,就要建大根堆。如果挤进来的东西比k多了,就踢掉一个最菜的即最远的。
细节:
1.实现大根堆时排序标准是距离,计算要用到Point自己本身之外的变量origin,注意因为我们写的inner class,所以要索取其他的变量必须要把它设为final。(或者你弄成全局也行,不过动不动弄全局不太好)。
2.大根堆的话就p2-p1反过来。
3.算距离的时候用了平方和。注意java里没有平方/幂次运算符,只有平方/幂次api。别傻兮兮地写x^2,^符号是异或啊亲,这是java不是matlab!用Math.pow(x, 2),不过这个返回类型是double也要额外小心。
4.int数字做平方和小心超界限,long或double走一个。
实现
/** * Definition for a point. * class Point { * int x; * int y; * Point() { x = 0; y = 0; } * Point(int a, int b) { x = a; y = b; } * } */ public class Solution { /** * @param points: a list of points * @param origin: a point * @param k: An integer * @return: the k closest points */ // private Point globalOrigin; public Point[] kClosest(Point[] points, Point origin, int k) { // write your code here if (points == null || origin == null || k < 0 || k > points.length) { return new Point[0]; } // globalOrigin = origin; // 确认是不是要这样?A: 是的!被内部类调用的外部变量需要设为final!或者全局。 final Point finalOrigin = origin; PriorityQueue<Point> maxHeap = new PriorityQueue<Point>(new Comparator<Point>() { @Override public int compare(Point p1, Point p2) { long diff = distance(p2) - distance(p1); if (diff > 0) { return 1; } else if (diff < 0) { return -1; } else if (p1.x != p2.x){ return p2.x - p1.x; } else { return p2.y - p1.y; } } private long distance(Point p) { return (long) (Math.pow(p.x - finalOrigin.x, 2) + Math.pow(p.y - finalOrigin.y, 2)); } }); for (Point point : points) { maxHeap.offer(point); if (maxHeap.size() > k) { maxHeap.poll(); } } Point[] result = new Point[k]; for (int i = result.length - 1; i >= 0; i--) { result[i] = maxHeap.poll(); } return result; } }