参考代码:
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int lo = 1;
int hi = n;
while(lo < hi) {
int mid = lo + (hi - lo) / 2;
if (isBadVersion(mid)) {
hi = mid;
} else {
lo = mid + 1;
}
}
return hi;
}
}
大致思路:先将所有数分成两半,判断中点是否为bad,是bad说明第一个出现错误的版本在mid及以前,所以把范围移到前面一半,再次判断mid是否为bad,反复对半缩减,直至缩减到只剩一个值,那么他就是第一个错误的版本。
具体实现:
首先取最大范围:lo=1,hi=n
判断mid是否为bad,这里值得注意的是mid = lo + (hi - lo) / 2;并不只是单纯的二分,是在lo的基础上在加上二分值,因为缩减范围的时候是向原有的左边或者右边缩减。
当isBadVersion(mid)为true时,说明bad在原来的的范围中左边的一半,所以需要向左缩减,及令hi=mid;
当isBadVersion(mid)为false时,说明bad在原来的的范围中右边的一半,所以需要向左缩减,及令lo=mid+1;因为已经确定[lo,mid]中没有bad,所以应该从mid+1开始。
最后lo=hi是跳出循环,返回第一个出现错误的版本。
到最后一定是相等的!因为当缩减到[lo,hi](hi=lo+1)时,mid=lo+(hi=lo)/2=lo+0=lo,因为已经确定hi处就是bad,所以mid=lo是就不为bad,进入if语句:lo=lo+1=hi,所以最后一定会相等。
例:n=7,bad=6;
首先mid=4,不为bad,向右缩减,lo=mid+1=5;
mid=6,为bad,向左缩减,hi=6;
mid=5,不为为bad,向右缩减,lo=mid+1=6;
lo=hi,返回6。