【leetcode】leetcode69 square root of x

Given a non-negative integer x, compute and return the arithmetic square root of x.

Since the return type is an integer, only the integer part of the result is kept, and the decimal part will be discarded.

Note: Any built-in exponential functions and operators such as pow(x, 0.5) or x ** 0.5 are not allowed.

Example 1:

Input: x = 4
Output: 2
Example 2:

Input: x = 8
Output: 2
Explanation: The arithmetic square root of 8 is 2.82842…, since the return type is an integer, the decimal part will be rounded off.

hint:

0 <= x <= 231 - 1

Source: LeetCode
Link: https://leetcode-cn.com/problems/sqrtx
Copyright belongs to LeetCode Network. For commercial reprints, please contact the official authorization, for non-commercial reprints, please indicate the source.

principle

Newton's method (used in numerical analysis):

In the iterative process, replace the curve with a straight line, replace the original curve with the first-order Taylor expansion (that is, the tangent at the current point), find the intersection point of the straight line and the xx axis, and repeat this process until convergence.

First guess an approximate value xx randomly, and then keep x equal to the average of x and a/x. After six or seven iterations, the value of xx is quite accurate. Construct the equation x − a 2 = 0, let f ( x ) = x − a 2 , and then continue to use the tangent of (x,f(x)) to continuously approach the equation $x^{2} $The
derivative of the above function is 2x, that is to say, any point on the function (x,f(x)) The slope of the tangent line at is 2x.

Then xf(x)/(2x) is an approximation closer to x. Substituting f ( x ) = x 2 − a can get x − ( x 2 − a ) / ( 2 x ) to get (x+ a/x)/2 where a is the target value
insert image description here

dichotomy

Since this question only requires the integer part after taking the square root, the search range is limited, and the dichotomy method can be considered.

Construct an array from 0 to input x, each element in the array is equal to its position, define two pointers, the left pointer left and the right pointer right, the initial positions are respectively located at both ends of the array;

Execute the loop. The control condition of the loop is that the left pointer cannot go to the right of the right pointer. Each cycle obtains the position of the midpoint, and checks the relationship between the square s of the number and the input x: (1) s ==
x : It is equivalent to finding the result of the square root, and return this number directly;
(2) s > x: the square result is larger, delete the right half of the array
(3) s < x: the square result is small, delete the left half of the array

When breaking out of the loop, return to the position of the right pointer.

solution

The idea of ​​using the binary search method to search for the square root is very simple. In fact, it is "guessing", but it is a strategic "guessing". Use the "exclusion method" to exclude half of the interval elements at a time in a limited interval, and only one is left. Number, this number is the square root integer rounded down required by the title.

When Newton's method was first proposed, it was used to solve the root of the equation. Its basic idea is to "replace the curve with a straight line" and search for an approximate solution to the equation in iterations.

Java implementation

example

public class Solution {
    
    

    public int mySqrt(int x) {
    
    
        if (x == 0) {
    
    
            return 0;
        }
        // 注意:针对特殊测试用例,例如 2147395599
        // 要把搜索的范围设置成长整型
        long left = 1;
        long right = x / 2;
        while (left < right) {
    
    
            // 注意:这里一定取右中位数,如果取左中位数,代码会进入死循环
            // long mid = left + (right - left + 1) / 2;
            long mid = (left + right + 1) >>> 1;
            long square = mid * mid;
            if (square > x) {
    
    
                right = mid - 1;
            } else {
    
    
                left = mid;
            }
        }
        // 因为一定存在,因此无需后处理
        return (int) left;
    }

}

Results of the

insert image description here

Python implementation

example

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int

        核心思想:
                1. 直接return int(sqrt(x)) 直接ac
                2. 使用暴力遍历方法 for i in range(1,x) 尝试 i*i 是否 == x 或者 i*i < x 但是 (i+1)(i+1) > x
                3. 使用牛顿法(数值分析中使用到的):
                    在迭代过程中,以直线代替曲线,用一阶泰勒展式(即在当前点的切线)代替原曲线,求直线与 xx 轴的交点,重复这个过程直到收敛。
                    首先随便猜一个近似值 xx,然后不断令x等于x和a/x的平均数,迭代个六七次后 xx 的值就已经相当精确了

                    构造方程x - a^{2} = 0,令f(x)=x-a^{2},然后不断用(x,f(x))的切线来不断逼近方程x^{2}
                    上述函数导数为2x,也就是说函数上任意一点(x,f(x))处的切线斜率为2x。
                    那么x-f(x)/(2x)就是一个比x更接近的近似值,代入f(x)=x^{2}-a可以得到x-(x^{2}-a)/(2x)
                    变形即可得到(x+a/x)/2 这里的a是目标值
        """
        if x == 0:
            return 0
        cur_x = x # 令初始值为x
        while cur_x-x/cur_x > 1e-6:
            cur_x = (cur_x + x/cur_x)/2 # 利用公式(x+a/x)/2计算得到新的a
        return int(cur_x)

if __name__ == '__main__':
    s = Solution()
    print(s.mySqrt(8))

Guess you like

Origin blog.csdn.net/u011397981/article/details/131932788