class Solution:
def maxDistance(self, A: List[int], m: int) -> int:
""" tc O(NlgM) sc O(1), M: diff of max(pos) - min(pos)
binary search: range [min-min, max-min], note ball has to be placed in position exists in A
intv: minimun distance between any two balls is intv
main idea: We want to find the maximum d such that count(d) == m.
"""
A.sort()
n = len(A)
def cnt_ball(intv):
cnt, pos = 1,A[0]
for i in range(1,n):
if A[i]-pos >= intv:
cnt += 1
pos = A[i]
return cnt
l,r = 0, A[-1]-A[0]
while l < r :
"""
here to note, if we are trying to look for bisect_right, better mid = r - (r-l)//2 with l = mid, right = mid-1, if trying to look for bisect_left, using m = l + (r-l)//2 with l = mid-1, r = mid
"""
mid = l + (r-l+1)//2 # or r-(r-l)//2
if cnt_ball(mid) < m : # inteval is too big
r = mid - 1
else:
l = mid
return l
optimization
class Solution:
def maxDistance(self, position: List[int], m: int) -> int:
n = len(position)
position.sort()
def count(d):
cnt,pre = 1, position[0]
for i in range(1,n):
if position[i] - pre >= d:
cnt += 1
pre = position[i]
if cnt >= m: # optimization: early termination
return True
return False
l,r = 0, (position[-1]-position[0])//(m-1)
while l < r:
mid = r - (r-l)//2
if count(mid):# >= m:
l = mid
else: # mid is too big
r = mid - 1
return l