@@ -12,4 +12,120 @@ def kClosest(self, points, k):
12
12
else :
13
13
heapq .heappush (h , (- d , x , y ))
14
14
15
- return [(x , y ) for _ , x , y in h ]
15
+ return [(x , y ) for _ , x , y in h ]
16
+
17
+
18
+ """
19
+ 1. Process `points` into `distances`.
20
+
21
+ 2. Binary search the "distance". For every distance:
22
+ Split the elements in `distances` by distance
23
+ Put the ones smaller to smaller.
24
+ Put the ones larger to larger.
25
+ If len(smaller)<=k, then all the elements in the smaller must belong to the `ans`, do the same thing to the larger.
26
+ Else we ignore the larger and do the same thing to the smaller again.
27
+
28
+ Time: O(N)
29
+ The binary search range in average is N, N/2, N/4... = 2N
30
+ Space: O(N)
31
+ """
32
+ class Solution (object ):
33
+ def kClosest (self , points , K ):
34
+ #[1]
35
+ maxD = float ('-inf' )
36
+ minD = float ('inf' )
37
+ distances = []
38
+ for x , y in points :
39
+ distance = ((x ** 2 + y ** 2 )** 0.5 )
40
+ distances .append ((distance , x , y ))
41
+ maxD = max (maxD , distance )
42
+ minD = min (minD , distance )
43
+
44
+ #[2]
45
+ ans = []
46
+ smaller = []
47
+ larger = []
48
+ while K > 0 :
49
+ #split distances into smaller and larger
50
+ distance = (maxD + minD )/ 2
51
+ for d , x , y in distances :
52
+ if d <= distance :
53
+ smaller .append ((d , x , y ))
54
+ else :
55
+ larger .append ((d , x , y ))
56
+
57
+ if len (smaller )<= K :
58
+ ans += smaller
59
+ K -= len (smaller )
60
+ distances = larger
61
+ minD = distance
62
+ larger = []
63
+ smaller = []
64
+ else :
65
+ distances = smaller
66
+ maxD = distance
67
+ larger = []
68
+ smaller = []
69
+
70
+ return [(x , y ) for _ , x , y in ans ]
71
+
72
+
73
+
74
+ """
75
+ Quick Select
76
+ Time: O(N)
77
+ Space: O(N), can be optimize to O(1).
78
+ """
79
+ class Solution (object ):
80
+ def kClosest (self , points , K ):
81
+ """
82
+ Start State:
83
+ i = s #next element after "SSS"s
84
+ t = s #unprocessed elements
85
+ j = e #next element after "LLLL"s
86
+
87
+ SSSPP?????LLL
88
+ i t j
89
+
90
+ End State:
91
+ SSSPPPPPLLLLL
92
+ i jt
93
+ """
94
+ def quickSelect (distances , s , e , k ):
95
+
96
+ pivot = distances [(s + e )/ 2 ][0 ]
97
+ i = s
98
+ j = e
99
+ t = s
100
+
101
+ while t <= j :
102
+ if pivot < distances [t ][0 ]:
103
+ distances [t ], distances [j ] = distances [j ], distances [t ]
104
+ j -= 1
105
+ elif pivot > distances [t ][0 ]:
106
+ distances [t ], distances [i ] = distances [i ], distances [t ]
107
+ i += 1
108
+ t += 1
109
+ else :
110
+ t += 1
111
+
112
+ if i - s >= k :
113
+ return quickSelect (distances , s , i , k )
114
+ elif j - s + 1 >= k :
115
+ return pivot
116
+ else :
117
+ return quickSelect (distances , t , e , k - (t - s ))
118
+
119
+ distances = []
120
+ for x , y in points :
121
+ distance = ((x ** 2 + y ** 2 )** 0.5 )
122
+ distances .append ((distance , x , y ))
123
+
124
+ kthSmallestDistance = quickSelect (distances , 0 , len (distances )- 1 , K )
125
+
126
+ ans = []
127
+ for d , x , y in distances :
128
+ if len (ans )== K : break
129
+ if d <= kthSmallestDistance : ans .append ((x , y ))
130
+
131
+ return ans
0 commit comments