LeetCode 69 Sqrt(x)

LeetCode 69 Sqrt(x)

Implement int sqrt(int x).
Compute and return the square root of x.

求n的平方根与求1n范围内的质数这两个问题都不能用单纯的搜索。如果只是遍历1n/2,则会LTE,因此需要采用别的算法。

1.二分法
常见二分搜索,可以将时间复杂度变为O(logn),这里需要注意的是返回值为int。

Input: 2 Return: 1
Input: 3 Return: 1

代码如下:

public class Solution {
    public int mySqrt(int x) {
        if (x <= 0) return 0;
        int left = 1, right = x, mid = left + (right - left) / 2;
        while (left <= right) {
            if (mid == x / mid) return mid;
            else {
                if (mid > x / mid) right = mid - 1;
                else left = mid + 1;
                mid = left + (right - left) / 2;
            }
        }
        return right;
    }
    
}

1.牛顿法
将求x=sqrt(n)的问题转为求方程f(x)=0的解:

![](http://www.forkosh.com/mathtex.cgi? f(x) = x^2 - n)

牛顿法可以很好快速求得f(x)=0的近似解,迭代公式如下:

![](http://www.forkosh.com/mathtex.cgi? x_2 = x_1 - \frac{f(x_1)}{f^{'}(x_1)} = x_1 - \frac{f(x_1)}{2x_1})

对于本题来说,f(x)的导数即为2x,问题可以进一步转为:

![](http://www.forkosh.com/mathtex.cgi? x_2 = x_1 - \frac{x^2_1 - n}{2x_1} = \frac{x_1}{2} + \frac{n}{2x_1})

收敛结果为|f(x)|

代码如下:

public class Solution {
    public int mySqrt(int x) {
        if (x <= 1) return x;
        double x1 = 0, x2 = 1;
        while (Math.abs(x1 - x2) > 0.000001) {
            x1 = x2;
            x2 = x1 / 2 + (double)x / (2 * x1);
        }
        return (int)x1;
    }
    
}

你可能感兴趣的:(LeetCode 69 Sqrt(x))