Add k closest points to origin (#435) · wxpython/algorithms@851dcb5 · GitHub
Skip to content

Commit 851dcb5

Browse files
vinceajcsgoswami-rahul
authored andcommitted
Add k closest points to origin (keon#435)
* Add k closest points to origin * Update heap init file * Add tests for k closest points to origin * Add k closest points link to README * Update k closest points to origin Co-Authored-By: vinceajcs <huangv@bc.edu>
1 parent 2a664a8 commit 851dcb5

4 files changed

Lines changed: 68 additions & 8 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions

algorithms/heap/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
from .binary_heap import *
22
from .skyline import *
33
from .sliding_window_max import *
4+
from .merge_sorted_k_lists import *
5+
from .k_closest_points import *
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""Given a list of points, find the k closest to the origin.
2+
3+
Idea: Maintain a max heap of k elements.
4+
We can iterate through all points.
5+
If a point p has a smaller distance to the origin than the top element of a heap, we add point p to the heap and remove the top element.
6+
After iterating through all points, our heap contains the k closest points to the origin.
7+
"""
8+
9+
10+
from heapq import heapify, heappushpop
11+
12+
13+
def k_closest(points, k, origin=(0, 0)):
14+
# Time: O(k+(n-k)logk)
15+
# Space: O(k)
16+
"""Initialize max heap with first k points.
17+
Python does not support a max heap; thus we can use the default min heap where the keys (distance) are negated.
18+
"""
19+
heap = [(-distance(p, origin), p) for p in points[:k]]
20+
heapify(heap)
21+
22+
"""
23+
For every point p in points[k:],
24+
check if p is smaller than the root of the max heap;
25+
if it is, add p to heap and remove root. Reheapify.
26+
"""
27+
for p in points[k:]:
28+
d = distance(p, origin)
29+
30+
heappushpop(heap, (-d, p)) # heappushpop does conditional check
31+
"""Same as:
32+
if d < -heap[0][0]:
33+
heappush(heap, (-d,p))
34+
heappop(heap)
35+
36+
Note: heappushpop is more efficient than separate push and pop calls.
37+
Each heappushpop call takes O(logk) time.
38+
"""
39+
40+
return [p for nd, p in heap] # return points in heap
41+
42+
43+
def distance(point, origin=(0, 0)):
44+
return (point[0] - origin[0])**2 + (point[1] - origin[1])**2

tests/test_heap.py

Lines changed: 21 additions & 8 deletions

0 commit comments

Comments
 (0)