Saturday, April 1, 2017

K Closest Points

题目很简单就是写一个PriorityQueue但是有不少语法上的难点
最大的问题是自定义的comparator要调用local variable 'origin'的时候,要求origin要么是final要么是global variable。具体的原理 还不是特别懂。
时间复杂度是O(nlogk)一个k size的heap把所有的input扫一遍
空间复杂度O(k)就是heap的size
另外一个点就是这里用的是一个max heap与平时用的min heap是正好相反的,需要特别注意,因为求的是closest points,所以pq满了以后就要把最远的点踢出去
/**
 * 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 = null;
    private int squareDistance(Point p1, Point p2) {
        return (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
    }
    public Point[] kClosest(Point[] points, Point origin, int k) {
        // Write your code here
        Point[] result = new Point[k];
        if (points == null || points.length == 0 || k <= 0) return result;
        globalOrigin = origin;
        PriorityQueue<Point> pq = new PriorityQueue<Point>(k, new Comparator<Point>() {
            @Override
            public int compare(Point p1, Point p2) {
                int diff = squareDistance(globalOrigin, p2) - squareDistance(globalOrigin, p1);
                if (diff == 0) {
                    if (p1.x != p2.x) {
                        return p2.x - p1.x;
                    } else {
                        return p2.y - p1.y;
                    }
                }
                return diff;
            }
        });
        for (int i = 0; i < points.length; i++) {
            if (pq.size() < k) {
                pq.offer(points[i]);
                continue;
            }
            int currDistance = squareDistance(globalOrigin, points[i]);
            if (currDistance < squareDistance(globalOrigin, pq.peek())) {
                pq.poll();
                pq.offer(points[i]);
            }
        }
     
        int index = pq.size() - 1;
        while (!pq.isEmpty()) {
            result[index--] = pq.poll();
        }
        return result;
     
    }
}

No comments:

Post a Comment