一 题目描述
实现 int sqrt(int x)
函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
二 解题思路
二分法查找法,找到相乘近似等于所传数值
以每一次的mid的平方来与x相比:
如果mid*mid == x,返回mid;
如果mid*mid < x,那么说明mid过小,应让low = mid+1,在右边继续查找
如果mid*mid > x,那么说明mid过大,应让high = mid-1,在左边继续查找
三 实例代码
public int sqrt(int x) {
int low = 0;
int high = x;
while(low<=high){
long mid = (long)(low + high)/2;
if(mid*mid < x)
low = (int)mid + 1;
else if(mid*mid > x)
high = (int)mid - 1;
else
return (int)mid;
}
return high;
}
优化点:由于mid×mid可能会超过int类型的范围,导致精度溢出,所以才得引进long类型,增加了空间,但可以用x除以除数得到的商是否等于除数来判断是否其平方根;
以每一次的x除以除数得到的商相比:
如果x/m == m,返回mid;
如果x/m > m,那么说明m过小,应让low = mid+1,在右边继续查找
如果x/m < m,那么说明mid过大,应让high = mid-1,在左边继续查找
优化后的算法代码实例如下:
public static int mySqrt(int x) {
int l=1, h=x;
int m, sqrt;
while(l<=h){
m = l + (h-l)/2;
sqrt = x/m;
if(sqrt==m){
return m;
}else if(sqrt>m){
l=m+1;
}else{
h=m-1;
}
}
return h;
}