- 二分查找算法介绍
- 二分算法实例
- 实例思路
- 代码
1、二分算法介绍
1.1概念
二分算法(Binary Search)是一种在排好序的数组中查找目标值的算法。它通过将目标值与数组中间元素进行比较,从而确定目标值可能存在的位置。如果目标值小于中间元素,就在数组的左半部分继续查找;如果目标值大于中间元素,就在数组的右半部分继续查找。通过每次将搜索范围缩小一半,最终可以快速找到目标值的位置或者确定其不存在。
1.2时间复杂度
二分算法的时间复杂度为 O(log n),其中 n 为数组的长度。
1.3二分算法的基本步骤
1.确定搜索范围的起始点和终点。
2.计算中间元素的索引,并取得该位置的元素值。
3.将目标值与中间元素进行比较,以确定下一步搜索的方向。
4.根据比较结果,缩小搜索范围并重复上述步骤,直至找到目标值或者确定其不存在。
2.二分算法实例——管道
2.1问题描述
有一根长度为 len 的横向的管道,该管道按照单位长度分为 len段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。一开始管道是空的,位于 Li的阀门会在 Si 时刻打开,并不断让水流入管道。对于位于 Li的阀门,它流入的水在 Ti(Ti≥Si)时刻会使得从第 Li−(Ti−Si)段到第 Li+(Ti−Si)段的传感器检测到水流,求管道中每一段中间的传感器都检测到有水流的最早时间。
2.2输入格式
输入的第一行包含两个整数 n,len,用一个空格分隔,分别表示会打开的阀门数和管道长度。 接下来 n行每行包含两个整数 Li,Si,用一个空格分隔,表示位于第 Li段管道中央的阀门会在 Si时刻打开。
2.3输出格式
输出一行包含一个整数表示答案。
2.4数据范围
对于 30%30% 的评测用例,n≤200,Si,len≤3000;
对于 70%70% 的评测用例,n≤5000,Si,len≤;
对于所有评测用例,1≤n≤1051,1≤Si,len≤,1≤Li≤len1,Li−1<Li。
2.5输入样例
3 10
1 1
6 5
10 2
2.6输出样例
5
3.实例思路
根据题目可知,管道的最大长度len可以达到,则可知最坏的情况为仅打开第一个阀门,打开的时间为
,则可得将在2*
-1的时候管道内充满水流。题目要求找到最短时间,则这个最短时间一定在0——2*
-1之间,取其中间数。采用二分查找的思想,当目的值小于这个中间数时,管道一定已经填满了,则在数组的左半部分查找;反之,管道一定未填满,则在数组的右半部分查找。重复以上步骤,直到找到最短时间位置。
注意,打开的阀门不止一个,判断函数要遍历每一个打开阀门在取不同时间Ti(Ti≥Si)时,其到达的其它阀门。
4.代码
def pan_duan(t1, l1, n2):
num1 = [False] * l1
for m in n2:
if t1 >= m[1]:
left = max(0, m[0] - (t1 - m[1]))
right = min(l1 - 1, m[0] + (t1 - m[1]))
for i in range(left, right + 1):
num1[i] = True
return all(num1)
def binary_search(len1, num2):
start1 = 0
end1 = pow(10, 9) * 2 - 1
while start1 < end1:
t = (end1 + start1) // 2
if pan_duan(t, len1, num2):
end1 = t
else:
start1 = t + 1
return start1
# 输入处理
if __name__ == "__main__":
num1, len1 = map(int, input().split())
num2 = []
for _ in range(num1):
num2.append(list(map(int, input().split())))
# 调用二分查找函数
result = binary_search(len1, num2)
print(result)
第一次在发表文章,有任何不足之处,欢迎在评论区指出。