有两个二分写法
- r = mid, l = mid + 1, m = (l + r) >> 1.求第一个小于x的数。,尽量往前。
- r = mid - 1, l = mid, m = (l + r + 1) >> 1.求第一个小于等于x的数,因为是小于等于,所以m的范围要尽量往后。
现在的写法是
while(r - l > 1)
mid = (l + r) >> 1;
if(check(mid))
l = mid;
else
r = mid;
答案是l
或者
while(r >= l)
{
int mid = (l + r) >> 1;
if(check(mid))
{
ans = mid;
l = mid + 1;
}
else r = mid - 1;
}
答案是ans
感觉二分有边界问题考虑,就是因为选取的是整数,导致mid并不是中心点。但是真正要讨论的部分,只有3个点的和2个点的时候。这个时候才会出现诸如答案选取,退出判断等问题。
开始的两种二分方法选择合理的话是不会有问题的。后面的两种二分方法则可能会出现丢失mid点答案的情况。比如l = 0,r = 4,那么取完mid = 2,后面r变成了1,此时mid变成了0。那么在二分结束的时候,1就判断不到。