题目:
69. x 的平方根
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
来源:力扣(LeetCode)
分析:
题目很简单,很容易就想到使用二分查找。
答案区间为 [left, right], 并且 mid = (left + right) >>>1
更新条件为:
if(mid * mid > x) right = mid - 1;
else left = mid;
上面的写法逻辑是正确的,但是会出现死循环的现象:当 (left + right) >>>1 与 left 相等时。
这时,其实就无法在缩小区间了。
而造成这种情况的原因是因为区间的大小为2了
[left, right] 满足 left + 1 == right ,所以一定满足 mid = (left + right) / 2 = (left + left + 1) / 2 = left
所以造成死循环的根本原因是使用了 : left = mid;这条语句!!!
我们在写二分查找时,只要避免了这条语句,就可以避免死循环了。
当更新条件需要 left = mid时,我们可以直接去判断 mid + 1的情况,
让更新变为 left = mid + 1,这样就不会在出现死循环了。
代码:
class Solution {
public int mySqrt(int x) {
int i = 0, j = (int)Math.sqrt(Integer.MAX_VALUE), mid, t;
while(i < j) {
mid = (i+j)>>>1;
t = mid * mid;
if(t == x) return mid;
else if(t > x) j = mid - 1;
//else i = mid; 会造成死循环
else if((mid+1)*(mid+1) > x) return mid;
else i = mid+1;
}
return i;
}
}