[leetcode/lintcode 题解] 微软面试题:K个最近的点
给定一些 points 和一个 origin,从 points 中找到 k 个离 origin 最近的点。按照距离由小到大返回。如果两个点有相同距离,则按照x值来排序;若x值也相同,就再按照y值排序。
在线评测地址:领扣题库官网
例1:
输入: points = [[4,6],[4,7],[4,4],[2,5],[1,1]], origin = [0, 0], k = 3 输出: [[1,1],[2,5],[4,4]]例2:
输入: points = [[0,0],[0,9]], origin = [3, 1], k = 1输出: [[0,0]]题解
使用 Heapify 的方法
heapify 时间复杂度 O(n) 然后 pop k 个点出来,时间复杂度 klogn 总共的时间复杂度 O(n+klogn)
如果 n >> k 的话,这种方法的时间复杂度是很优秀的。
public class Solution { private Point origin; private int size; /** * * * * */ public Point[] kClosest(Point[] points, Point origin, int k) { if (points == null || points.length == 0) { return points; } this.origin = origin; heapify(points); // O(n) Point[] results = new Point[k]; // O(klogn) for (int i = 0; i < k; i++) { results[i] = pop(points); } return results; } private void heapify(Point[] points) { size = points.length; for (int i = size / 2; i >= 0; i--) { siftDown(points, i); } } private void siftDown(Point[] points, int index) { while (index < size) { int left = index * 2 + 1; int right = index * 2 + 2; int min = index; if (left < size && compare(points[min], points[left]) > 0) { min = left; } if (right < size && compare(points[min], points[right]) > 0) { min = right; } if (index != min) { Point temp = points[index]; points[index] = points[min]; points[min] = temp; index = min; } else { break; } } } private Point pop(Point[] points) { Point top = points[0]; points[0] = points[size - 1]; this.size--; siftDown(points, 0); return top; } private int compare(Point a, Point b) { int square = distanceSquare(a, origin) - distanceSquare(b, origin); if (square != 0) { return square; } if (a.x != b.x) { return a.x - b.x; } return a.y - b.y; } private int distanceSquare(Point a, Point b) { return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); }}更多题解参考:九章官网solution
浙公网安备 33010602011771号