目录
069. x 的平方根
【题目】:
【代码】:
l,h,mid如果定义为int的话,当x过大,mid*mid可能会溢出,导致运行出错。
如下这么写就有问题:
public class Test069 {
public static void main(String[] args) {
int a=2147395599;
System.out.println(Math.sqrt(a)); //46339.999989210184
System.out.println(a/2); //1073697799
System.out.println(a/2 * a/2); //327565876
int b=mySqrt(a);
System.out.println(b); //-1
}
public static int mySqrt(int x) {
if (x <= 1) {
return x;
}
int l = 0, h = x;
while (l <= h) {
int mid = ( l + h ) / 2;
if (mid * mid <= x && (mid + 1) * (mid + 1) > x) {
return mid;
} else if (mid * mid < x) {
l = mid + 1;
} else {
h = mid - 1;
}
}
return -1;
}
}
744. 寻找比目标字母大的最小字母
【题目】:
【代码】:
278. 第一个错误的版本
【题目】:
【代码】:
【注意】:
(1)mid 的计算
有两种计算中值 mid 的方式:
- mid = (l + h) / 2
- mid = l + (h - l) / 2
l + h 可能出现加法溢出,也就是说加法的结果大于整型能够表示的范围。但是 l 和 h 都为正数,因此 h - l 不会出现加法溢出问题。所以,最好使用第二种计算法方法。
(2)循环条件和h=mid问题
isBadVersion(mid) = false,因此可以判断从l到mid都是false,因此 l = mid + 1,下一次的范围变为[mid + 1, right];isBadVersion(mid) = true,mid位置有可能是解,因此 h = mid,下一次的范围变为[left, mid],同时循环条件 while (l < h)。
(因为如果写成 “while(l<=h),h=mid”,当l=h,mid=l,isBadVersion(mid) = true的时候,h仍会等于mid,会造成死循环),因此:
- while(l < h) 对应 h=mid
- while(l <= h) 对应 h=mid-1