跳转至

69.Sqrt(x)

Tags: Binary Search Easy

Links: https://leetcode.com/problems/sqrtx/


Implement int sqrt(int x).

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

Example 1:

Input: 4
Output: 2

Example 2:

Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since 
             the decimal part is truncated, 2 is returned.

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

        return right;
    }
};

注意点就是mid的数据类型,可能出现溢出。二分法求解,速度一般,考虑数值分析里面的牛顿法、牛顿下山法和弦截法。弦截法的效率最高且不依赖初值,超线性收敛。

基于牛顿法的解法: $$ \displaystyle x_{k+1} =x_{k} -\frac{f( x_{k})}{f^{'}( x_{k})} \ \displaystyle f( x) = x^{2} -n $$ 所以把表达式代入化简即可。

class Solution {
public:
    int mySqrt(int x) {
        long res = x;
        while (res * res > x) {
            res = (res + x / res) / 2;
        }
        return res;
    }
};
Runtime: 0 ms, faster than 100.00% of C++ online submissions for Sqrt(x).
Memory Usage: 8.1 MB, less than 100.00% of C++ online submissions for Sqrt(x).

通常意义下的二分:

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

        return right;
    }
};