[leetcode 69] Sqrt(x)
题目
计算sqrt(x)的开方,结果为向下取整。
思路
思路1:用牛顿迭代法
牛顿迭代法是用来解
f(x)=0
的方程的解。牛顿的迭代法的原理图如下,摘自wiki百科:
可以看出,这条切线满足的方程是:
y=f′(xn)(x−xn)+f(xn)
,这个方程和
x
轴的交点写成迭代的形式
由于我们要解的方程是
x2−n=0
,因此,
xn+1=xn−x2n−n2xn
,化简得
xn+1=12(xn+nxn)
思路2:二分法查找
没什么好说的,最重要的是注意溢出问题。x*x == n应写成n/x == x
程序
牛顿迭代法:
public int mySqrt(int x) {
double k = 1;
if(x == 0 || x == 1)
return x;
while(true) {
double former = k;
k = (k+x/k)/2;
if(Math.abs(k-former) < 1) break;
}
return (int)k;
}
收藏一个好的
long r = x;
while (r*r > x)
r = (r + x/r) / 2;
return (int) r;
二分法:
自己最初写的很傻的程序:
public int mySqrt(int x) {
int low = 0;
int high = x/2+1;
long mid = low + (high-low)/2;
while(low <= high) {
if( ((mid*mid-x < 0) && ((mid+1)*(mid+1)-x > 0)) || mid*mid == x || (mid+1)*(mid+1) == x)
break;
if(mid*mid > x) {
high = (int) mid;
} else {
low = (int) mid;
}
mid = (int)(low + (high-low)/2);
}
if( (mid+1)*(mid+1) == x) return (int)mid+1;
return (int)mid;
}
收藏一个不错的
int sqrt(int x) {
if(x == 0 || x == 1){
return x;
}
int l = 1, r = x, res;
while(l <= r){
int m = (l + r)/2;
if(m == x / m){
return m;
}else if(m > x / m){
r = m - 1;
}else{
l = m + 1;
res = m;
}
}
return res;
}