题目
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
思路
1、因为 8 的平方根实际上是 2.82842,题目要求我们将小数部分舍去。因此输出 2。于是我们知道:由于输出结果的时候,需要将小数部分舍去,因此问题的答案,平方以后一定不会严格大于输入的整数。这里返回 3 就不对了,这是因为 32=9>8。
2、如果这个整数的平方 恰好等于 输入整数,那么我们就找到了这个整数;
如果这个整数的平方 严格大于 输入整数,那么这个整数肯定不是我们要找的那个数;
如果这个整数的平方 严格小于 输入整数,那么这个整数 可能 是我们要找的那个数;
3、上一个整数的平方根肯定不会超过它自己的一半,但是 0 和 1 除外,因此可以在 1 到输入整数除以 2 这个范围里查找要找的平方根整数。0 单独判断一下就行,而1-3的数的平方根肯定不会超过1,也单独判断一下。
代码
class Solution {
public int mySqrt(int x) {
if (x == 0) {
return 0;
}
if (x <= 3) {
return 1;
}
int l = 1, r = x / 2;
while (l <= r) {
int mid = l + (r - l) / 2;
// 直接定位
if (mid <= x / mid && (mid + 1) > x / (mid + 1)) { // 注意:这里为了避免乘法溢出,改用除法
return mid;
} else if (mid > x / mid) {
r = mid - 1;
} else {
l = mid + 1;
}
}
// 不会走到这里的
return 0;
}
}