求平方差 Sqrt(x)

问题:

Implement int sqrt(int x).

Compute and return the square root of x.

x is guaranteed to be a non-negative integer.

Example 1:

Input: 4
Output: 2

Example 2:

Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since we want to return an integer, the decimal part will be truncate

① 暴力破解,超时。

public class Solution {
    public int mySqrt(int x) {
        if (x <= 0) return 0;
        int res = 1;
        for (int i = 1;i * i <= x ;i ++ ) {
            if (i * i == x) {
                res = i;
                break;
            }else{
                res = i;
            }
        }
        return res;
    }
}

② 二分法,因为从1到sqrt(x)都是有序的,采用二分法可以更快的查找到结果。耗时3ms。

public class Solution {
    public int mySqrt(int x) {
        double diff = 0.01;//误差
        int start = 0;//不能写成double,否则输入为5时结果错误
        int end = x;

        while(start <= end){
            double mid = (end - start) / 2 + start;//定义为double类型,防止越界
            if (Math.abs(mid *mid - x) <= diff) {
                return (int)mid;
            }else if(mid * mid + diff < x){
                start = (int)mid + 1;
            }else if(mid * mid + diff > x){
                end = (int)mid - 1;
            }

        }
        return end;//不存在该根值时,返回最接近根值的
    }
}

另一种解法:

public class Solution {//4ms
    public int mySqrt(int x) {
        if (x < 0) {
            return -1;
        }
        long start = 0;//long类型 防止越界
        long end = x;
        while (start + 1 < end) {
            long mid = start + (end - start) / 2;
            if (mid * mid == x) {
                return (int) mid;
            }else if (mid * mid < x) {
                start = mid;
            }else {
                end = mid;
            }

        }
        if (end * end == x) {
            return (int) end;
        }else {
            return (int) start;
        }

    }
}

③ 使用牛顿迭代法求解:

给定一个正数a, 设其平方根为x,则有x^2=a,即x^2-a=0。设函数f(x)= x^2-a,则可得图示红色的函数曲线。在曲线上任取一点(x0,f(x0)),其中x0≠0那么曲线上该点的切线方程

                             (1-1)

该切线与x轴的交点

                            (1-2)

 

      因为1-2式中x0作为分母,所以在之前限定了一下初始值不要选0。那么得到的这个与x轴的交点其实是最终要求得的x的一次逼近,我们再以这个x基准继续迭代就可以求得更逼近的x,至于逼近到什么时候才算完,这个取决于你自己设定的精度。整个过程的迭代只需要几步就可以求得最终的结果。

代码如下:

public class Solution {//3ms
     public int mySqrt(int x) {
        if (x == 0) return 0;
        double pre = 0;
        double cur = 1;
        while(Math.abs(cur - pre) > 0.00001){
            pre = cur;
            cur = x / (2 * pre) + pre / 2.0;
        }
        return (int)cur;
    }
}

转载于:https://my.oschina.net/liyurong/blog/1143031

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值