二分查找基本原理

https://player.bilibili.com/player.html?aid=841423368&bvid=BV1d54y1q7k7&cid=216724849&page=1&high_quality=1

IMG_0691.jpg

重点边界条件是left+1<right,这样再执行一次恰好会使得l、r相邻(left<right)。

# 重点l初始值是数组的左边界,r的初始值是数组的右边界. 
# 如果二分查找的是数组,l、r的初始值要恰好在数组的范围外
l=-1, r=N  # 此处使用数组作为演示,数组的范围是[0,N-1]。所以1=-1,r=N
while l+1 <r:  # 只有l+1<r,再执行一次恰好会使得l、r相邻。如果是l<r,这样再执行一次就会编程l=r
	m=(l+r)>>1   # (l+r)/2向下取整
	if IsBlue(m) # 如果中间值m符合条件
		l=m
	else:
		r=m
# 重点根据题意判断应该返回l还是r
# 为了防止超出边界可以对l或者r进行规范max(0,l)、min(r,N-1)
nums[max(0,l)]       nums[min(r,N-1)]

经典二分查找算法

任务 示例 根据上述模板的基本思想如下
目标值是否存在 查找目标值
74. 搜索二维矩阵 第一个大于等于目标值的索引,然后判断第一个值是不是目标值
最后一个小于等于目标值的索引,然后判断最后一个是不是目标值
目标值在数组中第一个、最后一个位置 第一个错误的版本
在排序数组中查找元素的第一个和最后一个位置 第一个大于等于目标值的索引
最后一个小于等于目标值的索引
要插入的位置 搜索插入位置 第一个大于等于目标值的位置

查找目标值

74. 搜索二维矩阵 - 力扣(LeetCode)

278. 第一个错误的版本 - 力扣(LeetCode)

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣

35. 搜索插入位置 - 力扣(LeetCode)

数值二分型

如果符合有序这一特性的数值二分型题目同样可以使用上述模板。但是数值型不用考虑超出边界的问题。

题目 范围 特性 使用上述模板
374. 猜数字大小 [1,n] 单调递增 可以
367. 有效的完全平方数 正整数 单调递增 可以
x 的平方根 非负数 单调递增 可以

374. 猜数字大小 - 力扣(LeetCode)

367. 有效的完全平方数 - 力扣(LeetCode)

69. x 的平方根 - 力扣(LeetCode)