分析:
题意求最大化最小,类似这样的求最大化最小值、最小化最大值等都可以用二分搜索解决.
1.找到所有position的最大距离和最小距离;
2.通过二分法,分别判断满足条件的距离(a.mid=(最大距离+最小距离)/2;b.满足条件的点是否>=m);
下面是实现示例:
class Solution(object):
def check(self,p,mid,m):
c = 0
i,j=0,1
while j<len(p):
if p[j] - p[i] >= mid:
c+=1
i=j
j+=1
return c+1>=m
def maxDistance(self, position, m):
"""
:type position: List[int]
:type m: int
:rtype: int
"""
position = sorted(position)
min_d = position[-1] - position[0]
max_d = position[-1] - position[0]
for i in range(len(position)-1):
if min_d > position[i+1] - position[i]:
min_d = position[i+1] - position[i]
if m == 2:
return max_d
left,right = min_d,max_d
while left<=right:
mid = (left+right)/2
if self.check(position,mid,m):
left=mid+1
else:
right=mid-1
return left-1
class Solution:
def minimumTime(self, time: List[int], totalTrips: int) -> int:
time.sort()
left = 0
right = time[0]*totalTrips
while left<right:
mid = (left+right)//2
trips = 0
for t in time:
if t>mid:
break
trips += mid//t
if trips>=totalTrips:
right = mid
else:
left=mid+1
return left
此题使用二分才能通过。重点在于,根据题目,将问题转换成二分,
class TopVotedCandidate:
def __init__(self, persons: List[int], times: List[int]):
maxid = -1
self.p_c = {}
self.t_p = {}
self.t = times
for i,v in enumerate(persons):
self.p_c[v] = self.p_c.get(v,0)+1
max_c = self.p_c.get(maxid,0)
if self.p_c[v] >= max_c:
maxid = v
self.t_p[times[i]] = maxid
def q(self, t: int) -> int:
l = 0
r = len(self.t)-1
while l<=r:
m = (l+r)//2
if t>=self.t[m]:
l=m+1
else:
r=m-1
return self.t_p[self.t[l-1]]
# Your TopVotedCandidate object will be instantiated and called as such:
# obj = TopVotedCandidate(persons, times)
# param_1 = obj.q(t)
边排序后,确定2条较长边,然后通过二分法找最后一条边的范围。
class Solution:
def triangleNumber(self, nums: List[int]) -> int:
nums.sort()
L = len(nums)
ret = 0
for i in range(L):
for j in range(i-1,-1,-1):
l = 0
r = j-1
while l<=r:
m = (l+r)//2
if nums[m]+nums[j]>nums[i]:
r=m-1
else:
l=m+1
ret += (j-1-r)
return ret
此题核心是确定h指数为二分查找对象,二分每确定一个值,就判断一次是否满足要求;
class Solution:
def check(self,cs,m):
t = 0
for i in cs:
if i>=m:
t+=1
return t>=m
def hIndex(self, citations: List[int]) -> int:
l = 0
r = len(citations)
while l<=r:
m = (l+r)//2
if self.check(citations,m):
l=m+1
else:
r=m-1
return l-1
最主要的核心是获取最大最小天数,然后将天数进行二分,分别判断不同天数是否满足要求。
class Solution:
def check(self,arr,mid,m,k):
t = 0
ret = 0
for i in arr:
if i<=mid:
t+=1
else:
ret+=(t//k)
t=0
ret += (t//k)
return ret>=m
def minDays(self, bloomDay: List[int], m: int, k: int) -> int:
l = min(bloomDay)
r = max(bloomDay)
min_ = l
max_ = r
while l<=r:
mid = (l+r)//2
if self.check(bloomDay,mid,m,k):
r=mid-1
else:
l=mid+1
if l>max_ or l<min_:
return -1
return l