Sqrt
Implement int sqrt(int x).
Compute and return the square root of x.
二分搜索
复杂度
时间 O(1) 因为整数长度有限 空间 O(1)
思路
我们知道必定存在这么两个整数a和b,a^2 <= sqrt(x) <= b^2,所以我们要做的其实就是缩小这个ab的范围。使用二分法解这题时,通过比较mid^2和x大小来确定我们在哪一个半片中搜索。
注意
这题的边界条件较多,首先high要用long型存储,其次如果有必要的话要判断x是否是非负数。
代码
public class Solution {
public int mySqrt(int x) {
long low = 0 , high = x / 2;
while(low <= high){
int mid = low + (high - low) / 2;
if(mid * mid < x){
low = mid + 1;
} else {
high = mid - 1;
}
}
return (int)high;
}
}
牛顿迭代法
复杂度
时间 O(1) 空间 O(1)
思路
更好的解法是用数学方法,牛顿法是非常经典的求解方程的方法。其基本公式是$$ x_{2}=x_{1}-\frac{x_{1}^2-n}{2x_{1}} $$,其中x1是上次计算结果,x2是本次计算结果,当他的误差小于一定值时返回。初始x值可选n/2,或者神奇数0x5f37642f。
代码
public class Solution {
public int sqrt(int x) {
// 如果初始值取0x5f37642f,则会进一步加快计算速度
double x1 = x/2.0;
double x2 = 0.0, err = x2 - x1;
while(Math.abs(err)>0.00000001){
x2 = x1 - (x1 * x1 - x) / (2 * x1);
err = x2 - x1;
x1 = x2;
}
return (int)x2;
}
}