1.1.3 Arrays - Square of x (Leetcode 69)

1. Topic

Leetcode link
Given you a non-negative integer x, calculate 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

2. Idea

Since only the integer part is kept, ans is the largest k value that satisfies k 2 ≤ x

Solution 1: Find the square root of the logarithmic function
insert image description here
[Note: The return value is a floating-point number, which will cause precision problems]

Solution 2: binary search k

Solution 3: Newton iteration method

  1. Transform the problem into solving the zero point of the function
    insert image description here
  2. The essence of Newton's iterative method is to quickly approach zero from the initial value with the help of Taylor series.
    insert image description here
  3. Implementation process
    insert image description here
  4. implementation details
    insert image description here

3. Code implementation

Solution 2: binary search k

class Solution {
    
    
public:
    int mySqrt(int x) {
    
    
        int left = 0;
        int right = x;
        int ans = -1;

        while(left <= right){
    
    
            int middle = left + (right - left) / 2;
            if((long long)middle*middle <= x){
    
    
                ans = middle; // 满足条件的k, 最后更新得到ans
                left = middle + 1;
            }else{
    
    
                right = middle - 1;
            }
        }

        return ans;
    }

};

Complexity Analysis

  • Time complexity: O ( logx ) O(logx)O ( l o g x ) is the number of times required for binary search.
  • Space complexity: O ( 1 ) O(1)O(1)

Solution 3: Newton iteration method

class Solution {
    
    
public:
    int mySqrt(int x) {
    
    
        if (x == 0) return 0;

        // 设置迭代初始值
        double x0 = x;
        double C = x;

        while(true){
    
    
            double x1 = 0.5 * (x0 + C/x0); // 根据公式得到下一个点x(i+1)
            if(fabs(x1 - x0) < 1e-7) break;
            x0 = x1; // 更新点xi
        }

        return int(x0);

    }

};

Complexity Analysis

  • Time complexity: O ( logx ) O(logx)O ( log x ) , this method is quadratically convergent, faster than binary search .
  • Space complexity: O ( 1 ) O(1)O(1)

4. Summary

1. Overflow judgment

(long long)middle*middle <= x
  • Here the value range of middle is 0 <= middle <= 2 31 - 1, then 0 <= middle * middle < 2 62
  • And the value range of the int variable is 2 31 <= middle <= 2 31
  • Because the variable type needs to be converted to long

2. Knowing the slope of the straight line and a point on the straight line, the expression formula of the straight line equation

3. abs() and fabs()

  • abs( ) is mainly used to find the absolute value of an integer, in the "stdlib.h" (or) header file.
  • And fabs( ) is mainly to seek the absolute value of double and float type with higher precision requirements, in the <cmath> header file.
  • Both can be used when only #include <cmath>.

4. Correct the idiomatic writing of mathematics

 double x1 = 1/2 * (x0 + C/x0); // 根据公式得到下一个点x(i+1)

Written in this form, it will loop forever, because 1/2 here will get 0!

Guess you like

Origin blog.csdn.net/weixin_46297585/article/details/123218175