forked from keon/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]>
- Loading branch information
1 parent
2a664a8
commit 851dcb5
Showing
4 changed files
with
68 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
from .binary_heap import * | ||
from .skyline import * | ||
from .sliding_window_max import * | ||
from .merge_sorted_k_lists import * | ||
from .k_closest_points import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Given a list of points, find the k closest to the origin. | ||
Idea: Maintain a max heap of k elements. | ||
We can iterate through all points. | ||
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. | ||
After iterating through all points, our heap contains the k closest points to the origin. | ||
""" | ||
|
||
|
||
from heapq import heapify, heappushpop | ||
|
||
|
||
def k_closest(points, k, origin=(0, 0)): | ||
# Time: O(k+(n-k)logk) | ||
# Space: O(k) | ||
"""Initialize max heap with first k points. | ||
Python does not support a max heap; thus we can use the default min heap where the keys (distance) are negated. | ||
""" | ||
heap = [(-distance(p, origin), p) for p in points[:k]] | ||
heapify(heap) | ||
|
||
""" | ||
For every point p in points[k:], | ||
check if p is smaller than the root of the max heap; | ||
if it is, add p to heap and remove root. Reheapify. | ||
""" | ||
for p in points[k:]: | ||
d = distance(p, origin) | ||
|
||
heappushpop(heap, (-d, p)) # heappushpop does conditional check | ||
"""Same as: | ||
if d < -heap[0][0]: | ||
heappush(heap, (-d,p)) | ||
heappop(heap) | ||
Note: heappushpop is more efficient than separate push and pop calls. | ||
Each heappushpop call takes O(logk) time. | ||
""" | ||
|
||
return [p for nd, p in heap] # return points in heap | ||
|
||
|
||
def distance(point, origin=(0, 0)): | ||
return (point[0] - origin[0])**2 + (point[1] - origin[1])**2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters