本文参考:
分享丨【题单】二分算法(二分答案/最小化最大值/最大化最小值/第K小) - 力扣(LeetCode)
本文主要详细讲解基础的二分算法中的查找,包括原理和模板,并用leetcode和洛谷的一些例题来进行实际题目讲解,如果觉得有帮助或者写的不错可以点个赞
目录
二分查找算法介绍
什么是二分查找?
我觉得洛谷那个例子举的很好
在一本英语词典中翻找一个单词的时候,可以从前往后一面一面的翻找,这就是顺序查找
但是英语词典里面的单词是按照字典序排的,那么可以先翻到词典的页数中间位置,然后根据要查找的单词再从前或者往后翻
这种思想就是二分查找
注意,二分查找一般只适用于有序的数组
那二分查找步骤是什么呢?
基本步骤如下:
- 确定初始范围:将搜索范围设置,比如整个数组。
- 计算中间位置:找到当前搜索范围的中间位置。
- 比较与缩小范围:
- 如果中间位置的值是目标值,返回该位置。
- 如果目标值小于中间位置的值,缩小范围到左半部分。
- 如果目标值大于中间位置的值,缩小范围到右半部分。
- 重复步骤2和3,直到找到目标值,或者搜索范围为空(未找到目标值)
- 核心思想:每次迭代将搜索范围缩小一半
二分查找的代码怎么写呢?
代码编写思路:
根据二分查找的步骤,我们可以得出实际代码的大致的编写方法:
初始化:
- 定义两个指针,
left
和right
迭代搜索:
- 在
left
小于等于right
的情况下,重复以下步骤:
- 计算中间位置
mid
:mid
- 比较目标值
target
与arr[mid]
的大小:
- 如果
target
等于arr[mid]
,则找到了目标值- 如果
target
小于arr[mid]
,则目标值在左半部分,更新right
- 如果
target
大于arr[mid]
,则目标值在右半部分,更新left
结束条件:
- 如果在迭代过程中找到了目标值,返回目标值所在的位置。
- 如果
left
超过right
而没有找到目标值,说明目标值不在数组中,返回 -1 表示未找到
刚学习的可以根据上面的步骤尝试写一遍
根据上面步骤,我们可以写出以下代码(Python)(有详细注释):
闭区间写法:
def binary_search(arr: List[int], target: int) -> int:
'''
在有序数组中查找目标值的索引。
如果目标值存在,返回其索引;否则返回 -1。
参数:
arr (List[int]): 一个有序的整数数组。
target (int): 需要查找的目标值。
返回值:
int: 目标值的索引,如果不存在则返回 -1。
'''
# 初始化搜索范围的左右边界
left, right = 0, len(arr) - 1
# 当左边界不超过右边界时,继续搜索
while left <= right:
# 计算中间位置
mid = left + (right - left) // 2
# 如果中