二分查找
二分查找
zhou二分查找
二分查找也被称为折半搜索。
简介
在一个升序的数组里,它每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需到右侧查找;如果中间元素大于所查找的值同理,只需到左侧查找
算法实现
STL
lowr_bound
和upper_bound
C++ 标准库中实现了查找首个不小于给定值的元素的函数 std::lower_bound
和查找首个大于给定值的元素的函数 std::upper_bound
,二者均定义于头文件 <algorithm>
中。
二者均采用二分实现,所以调用前必须保证元素有序。
bsearch 函数
bsearch 函数为 C 标准库实现的二分查找,定义在 <stdlib.h>
中。在 C++ 标准库里,该函数定义在 <cstdlib>
中。qsort 和 bsearch 是 C 语言中唯二的两个算法类函数。
bsearch 函数相比 qsort(排序相关 STL)的四个参数,在最左边增加了参数「待查元素的地址」。之所以按照地址的形式传入,是为了方便直接套用与 qsort 相同的比较函数,从而实现排序后的立即查找。因此这个参数不能直接传入具体值,而是要先将待查值用一个变量存储,再传入该变量地址。
于是 bsearch 函数总共有五个参数:待查元素的地址、数组名、元素个数、元素大小、比较规则。比较规则仍然通过指定比较函数实现,详见 排序相关 STL。
bsearch 函数的返回值是查找到的元素的地址,该地址为 void 类型,找不该元素时会返回NULL。
与lowr_bound函数的区别就是,如果有重复值,bsearch函数返回的不一定是首个不小于定值的元素,有可能是中间的
建议使用lowr_pound和upper_bound函数
1 | auto it = lower_bound(prefixSum.begin(), prefixSum.end(), newTarget); |
手写代码模板
1 | int l,r; |
三种写法
闭区间
1 | int lower_bound(vector<int> &nums, int target) { |
左闭右开区间
1 | int lower_bound2(vector<int> &nums, int target) { |
开区间
1 | int lower_bound3(vector<int> &nums, int target) { |
三分法
如果需要求出单峰函数的极值点,通常使用二分法衍生出的三分法求单峰函数的极值点。
三分法与二分法的基本思想类似,但每次操作需在当前区间 [l,r](下图中除去虚线范围内的部分)内任取两点 lmid,rmid(lmid < rmid)(下图中的两蓝点)。如下图,如果 f(lmid)<f(rmid),则在 [rmid,r](下图中的红色部分)中函数必然单调递增,最小值所在点(下图中的绿点)必然不在这一区间内,可舍去这一区间。反之亦然。
结束
一眼顶针,鉴定为纯纯模板题