【LeetCode 69】
描述
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5
LeetCode 69
示例 1
输入:x = 4
输出:2
示例 2
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
题解
Solution 1
由于 n 2 \frac{n}{2} 2n * n 2 \frac{n}{2} 2n ≥ \geq ≥ n n n, 那么可得 n n n ≥ \geq ≥ 4。所以我们可以在[ 2 2 2, n 2 \frac{n}{2} 2n]范围内查找第一个数 i i i使得 i ∗ i i * i i∗i ≥ \geq ≥ n n n的数;
public int mySqrt1(int x) {
if (x == 0) {
return 0;
}
if (x < 4) {
return 1;
}
int left = 2;
int right = x / 2;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (mid == x / mid) {
return mid;
} else if (mid > x / mid) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left - 1;
}
Solution 2
牛顿迭代法:
本题实际示求解 x 2 − C = 0 x^2 - C = 0 x2−C=0的非法整数根, 套用牛顿迭代公式有 x j = 1 2 ( x i + C x i ) x_j = \frac{1}{2}(x_i + \frac{C}{x_i}) xj=21(xi+xiC),我们需要不断重复迭代使得 x j x_j xj和 x i x_i xi近似相等。
private static double EPSILON = 1e-6;
public int mySqrt2(int x) {
if (x == 0) {
return 0;
}
double i = x * 1.0;
double j = 0.5 * (i + x / i);
while (i - j > EPSILON) {
i = j;
j = 0.5 * (i + x / i);
}
return (int)i;
}