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; }}