Achieve sqrt (x): binary search method and Newton's method

Recently sneak brush every day to maintain a LeetCode simple questions feel, though simple question easily find AC, but if to understand all of its solution, but also to learn a lot of new knowledge, expand the breadth of knowledge.

This article comes from the idea of creation: the square root of LeetCode Problem 69. x

DESCRIPTION Title effect (do not want to jump links, can be seen here): Given a non-negative integer x , and returns the computing requirements x square root of (rounded). For example, 4 input, output 2; 8 input, output 2 (2.82842 square root ...... 8 is, since the return type is an integer, the fractional part is discarded). I.e. given a \ (X \) , we have to calculate the \ (\ lfloor \ sqrt {X} \ rfloor \) .

The simplest and most intuitive way to naturally traversing from 0, until the first of its squared value greater than \ (X \) is the number of \ (n-\) , then \ (n-1 \) that is the answer. For any \ (X \) , after which the square root must be in rounding \ ([0, x] \ ) on the interval, as follows:

int sqrt(int x)
{
    if (x == 0)
        return x;
    int ans = 1;
    while (ans <= x / ans)
        ans++;
    return ans - 1;
}

There are two points to note here:

  1. Code line 6, whilethe determination condition to avoid overflow. The probability of large, you might write while (ans * ans <= x), it is more natural, more intuitive, but ansa lot of the time value, ans * ansthe result may exceed the inttype of representation the maximum range. For example, we have to calculate such \ (X \) is the square root of rounding (which is \ (n-\) , i.e., \ (\ lfloor \ sqrt {X} \ = n-rfloor \) ), the algorithm will anstraverse to a first square exceeds \ (X \) values, i.e. \ (n + 1 \) stopped. If \ (X \) value is the intmaximum value that can be represented type, then when anstraversed \ (n + 1 \) , the calculation ans * ansresult to exceed the inttype represented range.
  2. Since the whilecycle of judgment, we use division instead of multiplication, and therefore anscan no longer be traversing from 0 (otherwise it will lead to division by zero). To this end, we can handle alone at the beginning of the algorithm \ (x = 0 \) situation, and then let ansstarting from 1 traversal.

As a simple question, such violence is a natural simple algorithm of AC. But its low efficiency (need to traverse \ (O (\ sqrt {n }) \) times), the time efficiency in LeetCode only about 5% faster than the user, using the C ++ language runtime average more than 90ms. Therefore, this article provides two more efficient algorithms: binary search method and Newton method.

1. binary search

If you continue to think about violence on the basis of solving the great probability would have thought solved by binary search.

Yes, thinking strategies to solve the violence, we are in the interval \ ([0, x] \ ) search for a solution, rather search domain \ ([0, x] \ ) is naturally ordered, naturally you can use binary search instead of linear Search to significantly improve search efficiency.

Furthermore, we can narrow our search range. Intuition tells us that, for a non-negative integer \ (X \) , which \ (\ sqrt {x} \ ) should not be greater than \ (X / 2 \) (for example, \ (\ = sqrt {25}. 5 \) , less than \ (25/2 = 12.5 \) ). We can prove that:

\ [\ Begin {aligned} & \ text {set} y = \ frac {x} {2} - \ sqrt {x}, \ text {the} y ^ \ prime = \ frac {1} {2} - \ frac {1} {2 \ sqrt {x}}, \\ [2ex] & \ text {so} y ^ \ prime = 0, \ text {available stagnation} x = 1, \\ [2ex] & \ text {if} x> 1 \ {when} text, y ^ \ prime> 0, \ text {i.e. when} x> 1 \ {when} text, y = \ frac {x} {2} - \ sqrt {x } \ text {monotonically increasing value}, \\ [2ex] & \ text {to be launched, when} x> 1 \ when the text {}, \ lfloor \ frac {x} {2} \ rfloor - \ lfloor \ sqrt {x} \ rfloor \ text {monotonically increasing value}, \\ [2ex] & \ text {and because when} x = 2 \ {when} text, \ lfloor \ frac {x} {2} \ rfloor - \ lfloor \ sqrt {x} \ rfloor = 0, \\ [2ex] & \ text {so when} x \ geq 2 \ {when} text, \ lfloor \ frac {x} {2} \ rfloor - \ lfloor \ sqrt {x} \ rfloor \ geq 0, \ text {i.e.} x \ geq 2 \ {when} text, \ lfloor \ frac {x} {2} \ rfloor \ geq \ lfloor \ sqrt {x} \ rfloor & \ text {(QED)} \ end {aligned} \]

By proving we can see that, when the request of \ (X \) greater than or equal \ (2 \) , the sqrt(x)search space for the \ ([. 1, X / 2] \) , for \ (x <2 \) case , we only to special treatment (here we can conclude: when \ (x \ geq 1 \) when, \ (\ lfloor \ X FRAC} {2} {\ + rfloor. 1 \ GEQ \ lfloor \ sqrt {X } \ rfloor \) , then treated separately \ (x <1 \) case). Code:

int sqrt(int x)
{
    if (x < 2)  // 处理特殊情况
        return x;
    
    int left = 1, right = x / 2;
    while (left <= right) {
        # 避免溢出,相当于 mid = (left + right) / 2
        int mid = left + ((right - left) >> 1);
        if (mid == x / mid)
            return mid;
        else if (mid > x / mid)
            right = mid - 1;
        else
            left = mid + 1;
    }
    return right;
}

Here to explain the last return value why right. For the binary search, it will continue to shrink to a search space left == right(on a binary search, much repeated here, can themselves manually analog), In this case mid, leftand rightthe value is equal to three ( mid = (left + right) / 2). The retracted condition of the search range of known binary search, left(or mid), on the left are less \ (\ lfloor \ sqrt {X} \ rfloor \) , right(or mid) the right value greater than \ (\ lfloor \ sqrt X} {\ rfloor \) , at this time ( whilethe last cycle) determines midthe square of xthe size, there are three cases:

  1. mid == x / mid. Directly in the circulation return midvalue.
  2. mid > x / mid. In this case, since midthe value of the left side are less \ (\ lfloor \ sqrt {X} \ rfloor \) , and the midvalue is greater than \ (X \) , then mid-1that is the answer. The branch in accordance with the conditions, execution right = mid - 1, we can see rightthe value of what value should be returned. In this case, the end of the cycle, should be returned right.
  3. mid <= x / mid. In this case mid, leftand rightit is calculated answer (right value greater than \ (\ lfloor \ sqrt {X} \ rfloor \) ). A branching conditions, execution left = mid + 1, ending cycle. At this time, midand righta value of the calculation result.

Integrated the above three can be seen, if whilethe cycle is completed, the rightstored value must be calculated results.

And before Violence compared using a binary thought to find solving sqrt(x)only loop through \ (O (\ lg {\ frac {x} {2}}) \) times; complex spatial degree \ (O (1) \ ) .

2. Newton - Raphson iteration method

Newton - Raphson iterative method (referred to as Newton's method) using the method to straight thinking on behalf of the song, is a function of solving, not just for solving the square root calculation. Of course, using Newton's method to solve a function there are many pits, but for solving evolution, the Newton's method is safe. On this method, you need to have some knowledge of higher mathematics, want to know details, refer to the link: How to explain in plain Newton iterative method for evolution? data analysis? - MA students answer

Simple to understand, you can refer to picture:

Source: Newton method and quasi-Newton method

Given an arbitrary non-negative integer \ (n-\) , we want to find a \ (X = \ lfloor \ n-sqrt {} \ rfloor \) , which is equivalent to the function we want to calculate \ (f (x) = x ^ 2 - n \) root. First, we need to give a guess \ (x_0 \) , might make \ (x_0 = \ FRAC {X} + {2}. 1 \) (see the first measure proof), then \ (f (x_0) \ ) tangent as a function of the tangent of (X \) \ intersection axis that is a value after iterations \ (x_1 \) . If \ (x_1 \) the result is not to be obtained, the iteration is continued, in \ (f (x_1) \) tangent as a function of the tangent and \ (X \) the intersection of the axes, namely after the second iteration value \ (x_2 \) . And so on, until \ (x_n = \ lfloor \ n-sqrt {} \ rfloor \) .

Now we derive iterative. For \ (x_i \) , which is the function value \ (F (x_i) \) , then for point \ ((x_i, F (x_i)) \) , can be lent tangent equation:

\[ \begin{align} &y - f(x_i) = f(x_i)^\prime(x - x_i) \\[2ex] \implies &y - (x_i^2 - n) = 2x_i(x - x_i) \\[2ex] \implies &y + x_i^2 + n = 2x_ix \end{align} \]

And because \ (x_ {i + 1} \) is a tangent (X \) \ intersection of the axis, so that it \ (Y = 0 \) , can be obtained:

\[ x_{i+1} = (x_i + n / x_i) / 2 \]

Now, we can write code in accordance with iterative:

int sqrt(int x)
{
    // 避免除零错误,单独处理 x = 0 的情况
    if (x == 0)
        return x;
    int t = x / 2 + 1;
    while (t > x / t)
        t = (t + x / t) / 2;
    return t;
}

In order to ensure that the algorithm is correct, we need some additional proof. First of all, it proves iterative monotonically decreasing:

\[ x_{i+1} - x_i = \left\lfloor \frac{1}{2} (x_i + \frac{n}{x_i}) \right\rfloor - x_i = \left\lfloor \frac{1}{2} (\frac{n}{x_i} - x_i) \right\rfloor \]

Found that in the interval \ ([\ sqrt {x} , + \ infty) \) a, \ (. 1 + X_ {I} - x_i <0 \) .

Then, we have to prove iterative can converge to \ (\ lfloor \ sqrt {n } \ rfloor \) of:

\[ x_{i+1} = \left\lfloor \frac{1}{2} \left( x_i + \left\lfloor \frac{n}{x_i} \right\rfloor \right) \right\rfloor = \left \lfloor \frac{1}{2} (x_i + \frac{n}{x_i}) \right \rfloor \geq \left \lfloor \frac{1}{2} \times 2 \times \sqrt{x_i \cdot \frac{n}{x_i}} \right \rfloor = \lfloor \sqrt{n} \rfloor \]

Therefore, when the whileend of the cycle, we can get the right answers.

About Newton's law seeking sqrt(x)the complexity of the time, the author is also not clear, there is understanding of children's shoes please share ~. But by querying the data, as well as the actual test, we can see the time efficiency of Newton's method is superior to the binary search algorithm.

Guess you like

Origin www.cnblogs.com/faterazer/p/11868603.html