- 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:
- Python (min) heap queue (priority queue)
Use heap queue to further optimize time complexity fromO(nlogn)
for sort toO(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])
- Define sort/heapify function
-
item
forheap queue
: -
key
forsort 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)]
-
Do not use
x^2
to represent. Usex**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.)" -
Construct a comparator:
If Point 2 cannot be used here, I will use a newType
to representtuple (-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
.
网友评论