二分法的基本原理:把有序数组一分为二,再一分为二,直到不能分为止(直到查找到我们想要的答案)
时间复杂度:o(log n)
空间复杂度:o(1)
算法分析:1,我们需要一个具有单调性的数组
2,我们需要运用left(数组的第一个元素,以下简称l)和right(数组的最后一个元素,以下简称r)设置middle,也就是数组中间的点,公式为(l+r)//2(或(l+r+1)//2,视情况而定)
3,如果l==r的话(视题而定嗷,这里笼统的说一下),咱们滴答案就找到啦
不懂就来看代码吧———
基础代码(二分查找)落谷p2249
# 2249ac
n,m= [int(i) for i in input().split()]
num=[int(i) for i in input().split()]
fnum=[int(i) for i in input().split()]# 输入处理
num.insert(0,0)# 数组前面插入0,l从1开始
for i in fnum:
l = 1
r = n
while l<=r:
if l == r:
if num[l] == i:# 如果找到的数字==目标数字,就返回答案
print(l,end=" ")
break
print(-1, end=' ')# 不等于就返回-1
break
mid=(l+r)//2# 一分为二
if num[mid]>=i:# 如果mid偏大,就保留左边较小的元素
r=mid
if num[mid]<i:# 如果mid偏小,就保留右边较大的元素
l=mid+1# +1是边界问题,边界问题很重(nan)要(gao)
进阶版代码(二分答案)落谷p5119
# 5119二分ac
def check(t):# t是设定一个最大等待时间的最小值
car = 1# 原始设定车有一辆
id = 1# 第一头牛等待的时间
get = 1# 设定第一头牛已经坐上车
for i in range(2,n+1):
get += 1# 来了一头牛
wt = data[i] - data[id]# 等待时间(当前这一头牛-第一头牛的等待时间)
if get > c or wt >t:# 如果到的奶牛的数量大于每辆大巴可以乘坐的牛数或等待时间超过设定时间就换下一辆车
get=1
id=i
car+=1
return car<=m# 车如果够就返回true
n,m,c=[int(i) for i in input().split()]
data=[int(i) for i in input().split()]
data.insert(0,0)# 熟悉的占位
data.sort()# 保证单调性
l = 0
r = data[-1]
while l<r:
mid = (l + r) // 2# 一分为二
if check(mid):# 请看上面函数
r = mid# 答案可以更小
else:
l = mid + 1# 答案小了,需要右边更大的元素