二分查找

tips:

1.二分查找并不一定需要单调性

2.如果有单调性,一定可以二分,可以二分的不一定非有单调性

3.二分的本质是每一次循环需要选择答案所在的区间,即更新l, r两个坐标

 

整数二分

对于整数二分,有两种方法,分别适用于两个不同的情况,即想找到红色线的蓝圈还是绿色线的蓝圈

如果想找红色线的蓝圈,则check(mid)的标准在判断mid是否在黑线上

1 if(check(mid)) //满足黑线的性质,红线的蓝圈在[l, mid],否则红线的蓝圈在[mid + 1, r]
2     r = mid;
3 else
4     l = mid + 1

如果想找绿线的蓝圈,则check(mid)的标准在判断mid是否在粉线上

1 if(check(mid)) //满足粉线的性质,绿线的蓝圈在[mid, r],否则绿线的蓝圈在[l, mid - 1]
2     l = mid;
3 else
4     r = mid - 1

trick:

每次先写一个check(mid),然后考虑true的情况如何更新,如果更新方式是l = mid,则mid = l + r +1 >> 1

1. 

1 mid = l+r+1 >>1  //要加1的原因:如果l = r -1,即l和r只差一个数,mid = l,为true的时候会死循环
2 if(check(mid)) [mid, r], l = mid
3 else [l, mid-1] r = mid-1

2. 

1 mid = l+r >>  1
2 if(check(mid)) [l, mid], r = mid
3 else [mid+1, r] l = mid+1

 浮点二分

对于浮点数二分,

1 while(r - l > 1e-8)
2 {
3      int mid = (l + r) / 2;
4     if(check(mid)) r = mid;
5     else l = mid;
6 }

 

posted @ 2019-07-08 19:28  roov  阅读(9)  评论(0编辑  收藏  举报