二分是一个看似很简单的搜索算法,但也是有讲究的,所以在这里,我整理一下模板
这个模板有几个易错点,我们挨个看看:
(1)l = mid +1, r = mid - 1 习惯性的错过mid
错的原因很简单,就是因为你每(l+r)/2一次,你就少了一个mid,因为你这样写,无论如何取不到mid,所以有些情况你就会错过最优解。
(2)mid = (l + r + 1) / 2 与 mid = (l + r) / 2
这样写是为了避免死循环
我们看模板1, 如果 mid = (l + r) / 2 的话,当 l = 3,mid = 3, r = 4的时候,触发l = mid这个条件,l 一直等于3,一直出不去循环
反观模板2,如果l = 3, mid = 3, r = 4; 触发 l = mid + 1, l == r 退出循环, 触发 r = mid,l == r退出循环所以模板一需要mid = (l + r) /2;
while(l < r)
{
mid = (l + r + 1)/2;
if(a[mid] <= x) l = mid;
else r = mid - 1;
}
while(l < r)
{
mid = (l+r)/2;
if(a[mid] >= x) r = mid;
else l = mid + 1;
}
(3)a[mid] < x, a[mid] > x 即带不带等号
这个是需要根据题意来定的,比如PTA advanced Level Practice 10,寻找一个等于n1这个数的进制,所以无论大于n1还是小于n1,等于都在区间之内