2018-10-20 K Closest Points [M]

  1. K Closest Points
    Given some points and an origin point in two-dimensional space, find k points which are nearest to the origin.
    Return these points sorted by distance, if they are same in distance, sorted by the x-axis, and if they are same in the x-axis, 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]]

"""
Definition for a point.
class Point:
    def __init__(self, a=0, b=0):
        self.x = a
        self.y = b
"""

import heapq

class Solution:
    """
    @param points: a list of points
    @param origin: a point
    @param k: An integer
    @return: the k closest points
    """
    def kClosest(self, points, origin, k):
        heap = []
        for p in points:
            dist = self.get_dist(p, origin)
            # put a tuple into heap queue
            heapq.heappush(heap, (-dist, -p.x, -p.y))
            if len(heap) > k:
                heapq.heappop(heap)
        
        heap.sort(reverse=True)
        return [Point(-x,-y) for (_, x, y) in heap]
        
    def get_dist(self, p, o):
        return (p.x - o.x)**2 + (p.y - o.y)**2

Notes:

  1. Python (min) heap queue (priority queue)
    Use heap queue to further optimize time complexity from O(nlogn) for sort to O(nlogk)
import heapq // cannot be placed in class
heap = []
heapq.heappush(heap, item)

Use negative sign to make reverse sorting (from min priority to max heap)

It even just needs one line, but time complexity is O(nlogn).

import nsmallest
return heapq.nsmallest(k, points, key=lambda p: [(p.x-o.x)**2 + (p.y-o.y)**2, p.x])
  1. Define sort/heapify function
  • item for heap queue:
  • key for sort list

The operator module functions allow multiple levels of sorting. This takes advantage of python. Even though it is not "expected" by interviewers (they expect a comparator), it at least helps solve problems!

>>> student_objects = [
        Student('john', 'A', 15),
        Student('jane', 'B', 12),
        Student('dave', 'B', 10),
]

>>> sorted(student_tuples, key=itemgetter(1,2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

>>> sorted(student_objects, key=attrgetter('grade', 'age'))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
  1. Do not use x^2 to represent. Use x**2 instead. Because ^ means bitwise XOR.
    "Each bit position in the result is the logical XOR of the bits in the corresponding position of the operands. (1 if the bits in the operands are different, 0 if they are the same.)"

  2. Construct a comparator:
    If Point 2 cannot be used here, I will use a new Type to represent tuple (-dist, -p.x, -p.y)

class Type:
    def __init__(self, dist, point):
        self.dist = dist
        self.point = point

    def cmp(self, other):
        if other.dist != self.dist:
            return other.dist - self.dist
        if other.point.x != self.point.x:
            return other.point.x - self.point.x
        return other.point.y - self.point.y

    def __lt__(self, other):
        return self.cmp(other) < 0
    def __gt__(self, other):
        return self.cmp(other) > 0
    def __eq__(self, other):
        return self.cmp(other) == 0

The take away is to how write cmp() in this problem. To compare point and other, __lt__(self, other) means point < other.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,458评论 0 10
  • 有缘自然来相会!我就这样来了。几天前我很不靠谱的放最爱我的人鸽子。来到了师傅这儿,遇见了他的表妹。说是表妹,其实是...
    渡把阅读 150评论 0 0
  • 今天第一天写四百字,还真是不习惯。由于课业繁忙以及职业因素,每天的四百字都像写日记一样。今天来说说自己效率低下的毛...
    最喜不过淡雅阅读 120评论 0 0
  • 今天的工作太忙了 还是昨天用的九九的群一共被动进入10个群,完成任务。 导致没有与其他同学聊如何爆粉和转化的事情。...
    倩语千寻阅读 131评论 0 0
  • 回家的时候本来是带了支笔的,不曾想没墨了,所以一直借故偷懒不写字,即使过年的小长假,我看见了太多,也想了太多....
    万俟堇阅读 307评论 0 1