-
Notifications
You must be signed in to change notification settings - Fork 43
/
k-closest-points-to-origin.py
129 lines (102 loc) · 3.75 KB
/
k-closest-points-to-origin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""
973. K Closest Points to Origin
Medium
Given an array of points where points[i] = [xi, yi] represents a point on the X-Y plane and an integer k, return the k closest points to the origin (0, 0).
The distance between two points on the X-Y plane is the Euclidean distance (i.e., √(x1 - x2)2 + (y1 - y2)2).
You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in).
Example 1:
Input: points = [[1,3],[-2,2]], k = 1
Output: [[-2,2]]
Explanation:
The distance between (1, 3) and the origin is sqrt(10).
The distance between (-2, 2) and the origin is sqrt(8).
Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.
We only want the closest k = 1 points from the origin, so the answer is just [[-2,2]].
Example 2:
Input: points = [[3,3],[5,-1],[-2,4]], k = 2
Output: [[3,3],[-2,4]]
Explanation: The answer [[-2,4],[3,3]] would also be accepted.
Constraints:
1 <= k <= points.length <= 104
-104 < xi, yi < 104
"""
# V0
# IDEA : sort + lambda
class Solution(object):
def kClosest(self, points, K):
points.sort(key = lambda x : x[0]**2 + x[1]**2)
return points[:K]
# V0'
# IDEA : sort + lambda
class Solution(object):
def kClosest(self, points, k):
def my_func(x, y):
return x**2 + y**2
# edge case
if not points:
return
points.sort(key= lambda (x, y) : my_func(x, y))
#print ("points = " + str(points))
return points[:k]
# V1
class Solution(object):
def kClosest(self, points, K):
# python sort list on lmabda func
# https://stackoverflow.com/questions/3216398/sorting-by-arbitrary-lambda
points.sort(key = lambda x : x[0]**2 + x[1]**2)
return points[:K]
# V2
# Time: O(n) on average
# Space: O(1)
# quick select solution
from random import randint
class Solution(object):
def kClosest(self, points, K):
"""
:type points: List[List[int]]
:type K: int
:rtype: List[List[int]]
"""
def dist(point):
return point[0]**2 + point[1]**2
def kthElement(nums, k, compare):
def PartitionAroundPivot(left, right, pivot_idx, nums, compare):
new_pivot_idx = left
nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
for i in range(left, right):
if compare(nums[i], nums[right]):
nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i]
new_pivot_idx += 1
nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right]
return new_pivot_idx
left, right = 0, len(nums) - 1
while left <= right:
pivot_idx = randint(left, right)
new_pivot_idx = PartitionAroundPivot(left, right, pivot_idx, nums, compare)
if new_pivot_idx == k - 1:
return
elif new_pivot_idx > k - 1:
right = new_pivot_idx - 1
else: # new_pivot_idx < k - 1.
left = new_pivot_idx + 1
kthElement(points, K, lambda a, b: dist(a) < dist(b))
return points[:K]
# V3
# Time: O(nlogk)
# Space: O(k)
import heapq
class Solution2(object):
def kClosest(self, points, K):
"""
:type points: List[List[int]]
:type K: int
:rtype: List[List[int]]
"""
def dist(point):
return point[0]**2 + point[1]**2
max_heap = []
for point in points:
heapq.heappush(max_heap, (-dist(point), point))
if len(max_heap) > K:
heapq.heappop(max_heap)
return [heapq.heappop(max_heap)[1] for _ in range(len(max_heap))]