SQRT (x)

Total Accepted: 93296 Total Submissions: 368340 Difficulty: Medium

Submission URL: https://leetcode.com/problems/sqrtx/

Implement int sqrt(int x).

Compute and return the square root of X.

**Analysis:**

Solution 1: Newton's Iterative Method (Newton Tangent method )

Newton's Method (Newton tangent method) was first proposed by Isaac Newton in the Flow Number Act (method of fluxions,1671, published in 1736 after Newton's death). Joseph Laverson also presented this method in an analysis Aequationum in 1690. It is a method proposed by Newton in 17th century to approximate the equations on the real and complex fields.

Blue Line representation equationf (x)and the red line represents the tangent. You can seex _{ n+1 is closer to the root x required by F than xn . }

Since Newton's iterative method can be used to solve the root of the equation, it is advisable to , for example, to try to solve its root. For this Order \ (f (x) = x^2-n\), which is equivalent to solving the solution f (x) =0, as shown.

First find an initial value \ (x_0\), if \ (x_0\) is not a solution, do a \ ((X_0,f (x_0)) \) The tangent of this point, and the intersection of the axis is \ (x_1\) . Similarly, if \ (x_1\) is not a solution, make a tangent of this point through \ ((X_1,f (x_1)) \), and the intersection of the axes is \ (x_2\) . etc... In this way, the solution of f (x) =0 can be approximated infinitely.

Determines whether there are two methods of solving the solution: 1. The value of the direct calculation determines whether f (x) is 0,2. Judge before and after two and whether infinite approach.

The tangent equation for this point \ ((X_i, F (x_i)) \) is , \ (f (x) = f (x_i) + F ' (x_i) (x-x_i \)

where \ (f ' (x_i) \) is the derivative of \ (f (x) \), the derivative in the subject is \ (2x\). Make the tangent equation equal to 0 (the longitudinal intercept takes 0), you can find it:

\ (x_{i+1}=x_i-\frac{f (x_i)}{f ' (x_i)}\)

Substituting \ (f (x) = x^2-n\), continue simplifying:

\ (x_{i+1}=x_i-\frac{x_i^2-n}{2x_i} = x_i-\frac{x_i}{2} + \frac{n}{2x_i} = \frac{x_i}{2} + \frac{n}{2x_i}\)

Based on the above iterative formula, we can give an algorithm to find square root. In fact, this is indeed the implementation of the open square function built into many languages. Newton's Iterative method is also suitable for solving the solution of other multiple equations.

AC Code:

#include <cstdio>
#include <climits>
#include <cmath>
using namespace std;
class Solution {
public:
int mySqrt (int x) {
if (x <0) return INT_MIN;
if (x == 0) return 0;
double pre = 0; // res and pre are the results of two adjacent iterations, and the adjacent value can also be represented by the variable adj
double res = 1; // start looking around 1, iteratively approximate the target value
while (abs (res-pre)> 0.000001) // The judgment condition is changed to res-pre> 0.000001 || res-pre <-0.000001, the running time does not change
{
pre = res;
res = (res + x / res) /2.0;
}
return int (res); // The return value must be int, which must be converted
}
};
// Here is the test
int main ()
{
int x1 = 7;
int x2 = 2222147483648;
int x3 = -5;
Solution sol;
int res1 = sol.mySqrt (x1);
int res2 = sol.mySqrt (x2);
int res3 = sol.mySqrt (x3);
printf ("% d \ n", res1);
printf ("% d \ n", res2);
printf ("% d \ n", res3);
return 0;
}

P.S: The subject is the square root of the solved integer, and the return value is also an integral type. A slight modification based on the above code can also be applied to double (method 1 only).

#include <cstdio>
#include <climits>
#include <cmath>
using namespace std;
class Solution {
public:
double mySqrt (double x) {
if (x <0) return INT_MIN;
if (x == 0) return 0;
double pre = 0;
double res = 1; // When the evaluated value is double, the initial value of the iteration cannot be 0
// double res = 0.000001;
// double next = 1; // res and pre are the results of two consecutive iterations (adjacent values)
while (abs (res-pre)> 0.000001) // The judgment condition is changed to res-pre> 0.000001 || res-pre <-0.000001, the running time does not change
{
pre = res;
res = (res + x / res) /2.0;
}
return (res);
}
};
// Here is the test
int main ()
{
double x1 = 7;
double x2 = 2222147483648;
double x3 = -5;
Solution sol;
double res1 = sol.mySqrt (x1);
double res2 = sol.mySqrt (x2);
double res3 = sol.mySqrt (x3);
printf ("% lf \ n", res1);
printf ("% lf \ n", res2);
printf ("% lf \ n", res3);
return 0;
}

PS: The initial value of the iteration cannot be 0 because the value being evaluated is double. The pre and RES can be replaced with res and next in this code, see the Notes section, and of course the pre is changed to next in the loop.

Solution 2: Two-part search method

?√ X?&NBSP; ≤ ( X/2 +1), as shown, there are x=1, 2, 4 total 3 integer intersections, x>4 after ?√ Span style= "Color:rgb (51,51,51); font-size:13px; line-height:20px ">x? Constant less than ( ? X/2 ? +1).

Can be opened in a new tab in the browser, high-definition

becauseint sqrt(int x)the accepted parameters and return values are of type int, so? √x?≤ (?X/2? + 1) is equivalent to a strong data type language (e.g. C + +, C, Java, etc.) √ x (target value) ≤x/2+1 (x is the natural number, non-negative integer). So **in [0, x/2+1]** This range of **binary search** , you can find the int square root of N, mid= (low+up)/2, its initial value is X/2, the result should be in [ The mid or up of the low and up] . If you use a weak data type language (such as PHP, Python, JavaScript, and so on) to implement this method, you need to ceiling or ceil to take the whole!

But this method does not apply to double, because this method takes advantage of the characteristics of the int type.

< Span style= "Color:rgb (51,51,51); font-size:13px; line-height:20px ">AC code:

#include <cstdio>
#include <climits>
using namespace std;
class Solution {
public:
int mySqrt (int x) {
if (x <0) return INT_MIN;
long long low = 0;
long long up = x;
while (low <= up)
{
long long mid = (low + up) / 2; // Take the intermediate value mid, if it is changed to bit operation here, the program will slow down!
long long square = mid * mid;
if (x == square) return mid; // the target value is equal to the square at mid, exit the loop exit early
else if (x> square) low = mid + 1; // The target value is greater than the square at mid, find it in the open interval (mid, up), and the lower bound value is adjusted to mid-1
else up = mid-1; // The target value is less than the square at mid, find it in the open interval [low, mid), and the value of the upper bound up is adjusted to mid + 1
}
return up;
}
};
// Here is the test
int main ()
{
int x1 = 7;
int x2 = 2222147483648;
int x3 = -5;
Solution sol;
int res1 = sol.mySqrt (x1);
int res2 = sol.mySqrt (x2);
int res3 = sol.mySqrt (x3);
printf ("% d \ n", res1);
printf ("% d \ n", res2);
printf ("% d \ n", res3);
return 0;
}

This code run time is 8 MS, defeated 39.64% C + + commits, divided by 2 to shift to right 1 bit, but slowed down, a few MS, only defeated the 4.39 C + + submission ...

RELATED links:

Http://www.cnblogs.com/AnnieKim/archive/2013/04/18/3028607.html (Method 1 Code test failed, Method 2 smooth)

HTTP://BLOG.CSDN.NET/BAIMAFUJINJI/ARTICLE/DETAILS/50390841 (refer to the export conditions of the cycle)

Leetcode 69. SQRT (x) Problem solving report "C library function Sqrt (x) simulation-square root"