您的位置:首页 > 职场人生

LeetCode 069 Sqrt(x)

2014-02-02 11:07 288 查看
题目

Implement 
int sqrt(int x)
.

Compute and return the square root of x.

不用翻译。 关键是注意到两个类型,参数 int ,返回也是 int 。另外,x是不能为负数的。

思路

1 很不好意思的说,我第一反应是先用 java 的库。

return (int) Math.sqrt(x)


成功编译过。。。

2 目的是练级,所以停止傻笑,继续思考。根据上面的测试,知道是截取整数部分,ok,暴力破解。i从1 开始一个一个试,只要 i * i 超过了 x ,那么答案就是 i -1 。其中i<=46340是偷鸡了,它为(int) sqrt(2^31),如果i超过了这个,i*i 会溢出。

if(n==0){
return 0;
}

int i=1;
while(i*i<=n&&i<=46340){

i++;
}
if(i*i==n){
return i;
}
else{
return i-1;
}


3 上面的做法太不优雅,有没有更加优雅的做法?

我们想到既然都要一个个加,为什么不能够二分法的加。那么我们只要能够知道最大值即可。我们知道答案肯定不会超过n/2+1,设它为最大值。然后每次找mid来计算,不行的话,就二分,最后找到答案。这次中间变量都用long,这样可以完整地存储超过int 的数据,最后截取部分,因为答案肯定是在int范围内,所以也不要紧。

public class Solution {
public int sqrt(int x) {
if(x==0){
return 0;
}
long i =1;
long j=x/2+1;
while(i<=j){
long  mid=i+(j-i)/2;
long temp = mid*mid;
if(temp==x){
return (int)mid;
}
else if(temp<x){
i=mid+1;
}
else {
j=mid-1;
}
}

return (int)j;

}
}
4 但是这个做法,只适用于int ,如果参数double ,返回double,怎么办?

 网上看到牛顿迭代法(后悔大学数学没学好啊),参考了其他大牛的写法。

double sqrt(double x) {
2     if (x == 0) return 0;
3     double last = 0.0;
4     double res = 1.0;
5     while (res != last)
6     {
7         last = res;
8         res = (res + x / res) / 2;
9     }
10     return res;
11 }


测试

1 极限情况 x =0 x = 负数 

2 正常情况  3 5 35 

3 正好平方的情况  4 1 16

4 大数情况  46340 46341
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 面试笔试