标签:二分 right 找到 mid 查找 三分 模板 left
二分
理解
- while(left<=right),答案一定在[left,right]中。
- 思想有两种
- 通过缩小范围来快速找到目标数的位置(应用1)--- 找到答案终止循环
- 不断舍弃答案不可能存在的区间来逼近真实答案,若答案为整数,则可以正好找到该答案,若为实数则会找到在某个精度内的答案(应用2,3)--- 把循环全走一边结束
STL中给出的函数
lower_bound
upper_bound
应用题型
- 查找(找到指定数字即可、有重复数字时查找第一个、找比指定数大的...)
- 求单调函数零点
- 最大化最小值、最小化最大值
- 快速幂
查找
1.查找指定数字
例题: Can you find it? HDU - 2141
- 二分模板
int bsearch()
{
int left = 0,right = n,mid;
while(left<=right)
{
mid = left+(right-left)/2;
if(a[mid]==x)
return mid;
else if(a[mid]<x)
left = mid+1;
else
right = mid-1;
}
return -1;
}
查找到就返回mid下标,没找到就返回-1了。循环的终止是靠找到后return跳出,或者没找到while判断失败结束。
模板的使用有几处注意事项:
- 首先是mid = left+(right-left)/2,此处这么写是有原因的,若写mid = (right+left)/2则在数组开的很大的时候,作为下标,虽然数组本身下标可以用int 表示,但right和left相加容易int溢出。写mid = left/2+right/2就更不行了,这个很有可能死循环,如left=1,right=1,mid=0(自己掉过的坑)。
- 还有就是循环条件和left、right的变换方式要匹配,要么就全按照模板这样写,还有其它种写法,若是整数的搜索,按照模板没问题的,因为模板会遍历到所有数。详细解释:转载
- 没有常数步进容易造成死循环,详细解释:转载
二分法的查找过程就是二叉排序(查找、搜索)树
求单调函数零点
例题:Can you solve this equation? HDU - 2199
这种应用不是找到真正的解,而是在一定的精度范围内就可以了,所以循环的终止并不是靠a[mid] = x,而是靠while的条件如right-left<1e8,因为结果一定是在这个区间内的,所以当结果可能的取值范围在 1e8 说明精度就在 1e8 了,就可以结束了。
最小化最大值
这种二分的使用,实际上是有技巧的枚举,答案为已知区间的整数,所以就可以将这个区间内的所有整数全判断一遍,但这种方法肯定就爆炸了,所以要在枚举的同时带技巧--二分是把肯定不成立的区间从可能解中删去
标签:二分,right,找到,mid,查找,三分,模板,left 来源: https://blog.csdn.net/qq_39352598/article/details/81202575
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。