69. x 的平方根
题目描述
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
友情链接
思路解析
求 x 的平方根,x 等于什么呢?我们先假设 x 的平方根是 ans, 那么算式就是 ans * ans = x 。结合这道题可以理解成我们的目标就是循环查找,直到找到最大的数,这个数就是 ans 。这道题我采用二分查找法,查找范围是 range[1,x],直至找到最大的边界值。在每一次迭代过程中,都求出中位数 mid 和 x/mid ,通过比较 mid 和 x/mid 来确定下一轮循环的左右边界。
算法实现
class Solution {
public int mySqrt(int x) {
int left=1;
int right=x;
int ans=0;
while(left<=right){
int mid=left+(right-left)/2;
if(mid<=x/mid){
left=mid+1;
ans=mid;
}else{
right=mid-1;
}
}
return ans;
}
}
进阶设计
通过二分查找结合牛顿迭代法来求 x 的平方根。但是在定义变量时需要注意溢出的问题。注意看这里 ans 定义的是 long ,最终结果返回的时候再将 long 强转成 int 。
class Solution {
public int mySqrt(int x) {
long ans=x;
while(ans*ans>x){
ans=(ans+x/ans)/2;
}
return (int)ans;
}
}
牛顿法的原理可参考下图。
一开始随便定义 ans 的值,因为在通过 ans * ans > x 判断后能够迅速缩小查找范围。在有限次迭代求解后 ans 不断逼近 x 的平方根。
运行结果:
第一种二分查找法执行用时 2ms 。内存消耗 35.5MB 。 第二种结合牛顿迭代法执行用时 也是 2ms 。内存消耗 35.6MB 。
可以看出这两种算法在性能上没有什么区别。