1. 二分查找
- 寻找一个数
def binarySearch(self, nums: List[int], target: int) -> int:
left=0
right=len(nums)-1 #注意n 区间是[left,right]
while(left<=right): #注意<=
mid=int(left+(right-left)/2)
if(nums[mid]==target):
return mid
elif(nums[mid]>target): #注意+1 -1
right=mid-1
else:
left=mid+1
return -1 #注意没找到返回-1
- 寻找左侧边界
def left_bound(self, nums: List[int], target: int) -> int:
left=0
right=len(nums) #注意 区间是[left,right)
while(left<right): #注意 <
mid=int(left+(right-left)/2)
if nums[mid]>=target: #注意 找左边界 如果当前mid的值大于或等于target 则收缩右边界 每一次搜索区间 [left,mid),mid,[mid+1,right)
right=mid
else:
left=mid+1
return left #注意 返回left
- 寻找右侧边界
def right_bound(self, nums: List[int], target: int) -> int:
left=0
right=len(nums) #注意 区间是[left,right)
while(left<right): #注意 <
mid=int(left+(right-left)/2)
if nums[mid]<=target: #注意 找右边界 如果当前mid的值小大于或等于target 则收缩左边界
left=mid+1
else:
right=mid
return left-1 #注意 mid=left-1
- 二分+线性搜索
⾸先,你要从题⽬中抽象出⼀个⾃变量 x,⼀个关于 x 的函数 f(x),以及⼀个⽬标值 target。
同时,x, f(x), target 还要满⾜以下条件:
x:一般求啥 啥就是x
f(x) :必须是在 x 上的单调函数(单调增单调减都可以)
target:题⽬是让你计算满⾜约束条件 f(x) == target 时的 x 的值。
注意要根据题目确定left和right的值的范围,看清楚是左边界还是右边界,这两题都是找最慢速度 最小运输量,所以是左边界,计算的时候还要想清楚函数f和mid的关系是单调递增还是递减。
力扣 875. 爱吃香蕉的珂珂
class Solution:
def f(self, piles: List[int], x: int)-> int:
return sum([ceil(p / x) for p in piles])
def minEatingSpeed(self, piles: List[int], h: int) -> int:
left=1
right=1000000000+1
while(left<right):
mid=int(left+(right-left)/2)
if self.f(piles, mid)<=h:
right=mid
else:
left=mid+1
return left
class Solution:
def f(self, weights: List[int], x: int) -> int:
ans=1
sum=0
for w in weights:
sum+=w
if sum>x:
ans+=1
sum=w
return ans
def shipWithinDays(self, weights: List[int], days: int) -> int:
left=0
right=1
for w in weights:
left=max(left,w)
right+=w
while(left<right):
mid=int(left+(right-left)/2)
if self.f(weights, mid) <= days:
right=mid
else:
left=mid+1
return left