题目链接:
题目:
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.
题目分析:
实现求x的平方根的功能。
解题思路:
哈哈哈,直接调用Java的函数就解决了,不过这样子这道题就没意思了,这道题就是要求自己编写实现求平方根的功能。
思路一、根据数学推导
(x/2+1)^2=x^2/4+x+1 > x
所以 x 的平方根的范围在 [0,x/2+1] 然后利用二分查找即可,通过找到 mid后,验证 mid*mid,(mid+1)*(mid+1) ,(mid-1)*(mid-1) 和 x 的关系,如果找到刚好在这里,那么就返回 mid 或者 mid-1等。不然就继续二分查找缩小范围。
这里注意的一个点,就是 求 mid*mid 的时候,可能会超过 int 范围,所以二分查找的 参数,left,right,mid都用long 型。
思路二、牛顿迭代法
假设要求的平方根为 x,对应的输入值为 n。那么就是求 f(x)=x^2-n = 0 的根。
所以根据关系可得
x_n+1 = x_n - (x_n^2 - n)/(2*x_n) = 0.5*(x_n+ n/x_n);
所以用last 和 next 两个 double型变量记录,初始化,last = 0,next = 输入值。
然后不断的计算新的 next,把上一个的next 值保存在 last中。不断迭代,迭代结束的条件就是两次迭代值相差不大,因为这里最后输出只要整数即可。
就认为连续迭代两次值的差,小于0.01即认为迭代结束,认为已经求到了具体的平方根值,然后返回值(变成 int 进行返回)。
AC代码:(Java)
思路一(二分查找):
class Solution {
public int mySqrt(int x) {
long left = 0;
long right = x/2+1;
while(left < right)
{
long mid = (left+right)/2;
long res = mid*mid;
if(res > x)
{
right = mid-1;
res = right*right;
if(res < x)
return (int)right;
}
else if(res < x)
{
left = mid+1;
res = left*left;
if(res > x)
return (int)mid;
}
else if(res == x)
return (int)mid;
}
return (int)left;
}
}
思路二(牛顿迭代法)
class Solution {
public int mySqrt(int x) {
final double EXP = 1e-2;
double last = 0;
double next = x;
while(Math.abs(last-next) > EXP)
{
last = next;
next = 0.5*(next+x/next);
}
return (int)next;
}
}