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

ethannnli
858 声望360 粉丝