大厂面试真题详解:K个最近的点

简介: 大厂面试真题详解: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;
    
    /**
     * @param points a list of points
     * @param origin a point
     * @param k an integer
     * @return the k closest points
     */
    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

相关文章
|
Serverless C语言 索引
华为面试C语言真题(二)
华为面试C语言真题( 二)
305 1
华为面试C语言真题(二)
|
安全 测试技术 Python
软件测试面试题及答案,这个题库有3千多道最新面试真题可以刷
相信对于很多软件测试新手来说,技术项目的面试是十分让人头疼的,生怕没回答得好,就会跟这个offer失之交臂
205 0
|
设计模式 缓存 算法
腾讯Java高级岗180道面试真题,面试大厂拿45Koffer没问题!
一、数据结构与算法基础 · 说一下几种常见的排序算法和分别的复杂度。 · 用Java写一个冒泡排序算法 · 描述一下链式存储结构。 · 如何遍历一棵二叉树? · 倒排一个LinkedList。 · 用Java写一个递归遍历目录下面的所有文件
|
消息中间件 NoSQL 网络协议
字节跳动三面Java经历,砍下年薪50W的Offer,面试真题整理分享
应广大读者要求,今天开更一些大厂的面经和相关的面试干货,下面这份**最新字节跳动春招面经+笔记**带给大家。
153 0
字节跳动三面Java经历,砍下年薪50W的Offer,面试真题整理分享
|
NoSQL 算法 Dubbo
Java工程师丨面试真题(二)
Java工程师丨面试真题(二)
Java工程师丨面试真题(二)
Java工程师丨面试真题(一)
Java工程师丨面试真题(一)
|
存储 自然语言处理 前端开发
【牛客刷题】大厂真题 | 前端面试篇(一)
【牛客刷题】大厂真题 | 前端面试篇(一)
193 0
|
人工智能 Java 测试技术
【牛客刷题系列】Java工程师 | 百度面试真题(二)
【牛客刷题系列】Java工程师 | 百度面试真题(二)
123 0
|
Java
【大厂真题实战】Java工程师 | 字节面试真题(一)
【大厂真题实战】Java工程师 | 字节面试真题(一)
139 0