这道题还是二分查找,但是注意判断的时候用除法,防止大数相乘导致溢出
本人笨拙代码如下.........ORZ
class Solution {
public int mySqrt(int x) {
if(x<1)
return 0;
if(x>=1&&x<4)
return 1;
if(x>=4){
int l=0;
int r=x;
int m=(l+r)/2;
boolean flag=false;
while(!flag){
m=(l+r)/2;
if(x/m<m){
//避免溢出,应该用除法
if(m-x/m>=2){
r=m;
}else{
flag=true;
m=m-1;
}
}else if(x/m>m){
if(x/m-m>=2){
l=m;
}else{
flag=true;
}
}else{
flag=true;
}
}
return m;
}
return 0;
}
}
贴一个leetcode上面边界不一样的题解,边界写成我分不清的样子,很没有边界感bushi。作者是leetcode的liweiwei1419
class Solution {
public int mySqrt(int x) {
if(x==0)
return 0;
if(x==1)
return 1;
int left = 1;
int right = x / 2;
// 在区间 [left..right] 查找目标元素
while (left < right) {
int mid = left + (right - left + 1) / 2;
// 注意:这里为了避免乘法溢出,改用除法
if (mid > x / mid) {
// 下一轮搜索区间是 [left..mid - 1]
right = mid - 1;
} else {
// 下一轮搜索区间是 [mid..right]
left = mid;
}
}
return left;
}
}
除此以外,还可以用牛顿迭代,这里贴一个leetcode上面的题解,作者LOAFER
class Solution {
int s;
public int mySqrt(int x) {
s=x;
if(x==0) return 0;
return ((int)(sqrts(x)));
}
public double sqrts(double x){
double res = (x + s / x) / 2;
if (res == x) {
return x;
} else {
return sqrts(res);
}
}
}