二分模板 from y总

二分是一个看似很简单的搜索算法,但也是有讲究的,所以在这里,我整理一下模板

这个模板有几个易错点,我们挨个看看:

(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,等于都在区间之内

你可能感兴趣的:(算法)