-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy path658.Find-K-Closest-Elements.py
61 lines (51 loc) · 1.63 KB
/
658.Find-K-Closest-Elements.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
# https://leetcode.com/problems/find-k-closest-elements/description/
#
# algorithms
# Medium (34.83%)
# Total Accepted: 28.7k
# Total Submissions: 82.4k
# beats 77.85% of python submissions
class Solution(object):
def findClosestElements(self, arr, k, x):
"""
:type arr: List[int]
:type k: int
:type x: int
:rtype: List[int]
"""
def get_insert_idx(length):
head, tail, middle = 0, length - 1, None
while head < tail:
middle = head + (tail - head) / 2
if arr[middle] == x:
return middle
elif arr[middle] < x:
head = middle + 1
else:
tail = middle
return tail
length = len(arr)
x_idx = get_insert_idx(length)
if x_idx == 0:
return arr[:k]
elif x_idx == length - 1:
return arr[-k:]
else:
if arr[x_idx] != x:
x_idx = x_idx - \
1 if abs(arr[x_idx - 1] -
x) <= abs(arr[x_idx + 1] - x) else x_idx + 1
left, right = x_idx - 1, x_idx + 1
for i in xrange(k - 1):
if left < 0:
right += (k - 1 - i)
break
elif right == length:
left -= (k - 1 - i)
break
else:
if abs(arr[left] - x) <= abs(arr[right] - x):
left -= 1
else:
right += 1
return arr[left + 1:right]