LeetCode【#69】 Sqrt(x)(x的平方根)

题目链接:

点击跳转

 

题目:

Implement int sqrt(int x).

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

Example 1:

Input: 4
Output: 2

Example 2:

Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since 
             the decimal part is truncated, 2 is returned.

题目分析:

实现求x的平方根的功能。

 

解题思路:

哈哈哈,直接调用Java的函数就解决了,不过这样子这道题就没意思了,这道题就是要求自己编写实现求平方根的功能。

思路一、根据数学推导

(x/2+1)^2=x^2/4+x+1 > x

所以 x 的平方根的范围在 [0,x/2+1] 然后利用二分查找即可,通过找到 mid后,验证 mid*mid,(mid+1)*(mid+1) ,(mid-1)*(mid-1) 和 x 的关系,如果找到刚好在这里,那么就返回 mid 或者 mid-1等。不然就继续二分查找缩小范围。

这里注意的一个点,就是 求 mid*mid 的时候,可能会超过 int 范围,所以二分查找的 参数,left,right,mid都用long 型。

思路二、牛顿迭代法

假设要求的平方根为 x,对应的输入值为 n。那么就是求 f(x)=x^2-n = 0  的根。

所以根据关系可得

x_n+1 = x_n - (x_n^2 - n)/(2*x_n) = 0.5*(x_n+ n/x_n);

所以用last 和 next 两个 double型变量记录,初始化,last = 0,next = 输入值。

然后不断的计算新的 next,把上一个的next 值保存在 last中。不断迭代,迭代结束的条件就是两次迭代值相差不大,因为这里最后输出只要整数即可。

就认为连续迭代两次值的差,小于0.01即认为迭代结束,认为已经求到了具体的平方根值,然后返回值(变成 int 进行返回)。

 

AC代码:(Java)

思路一(二分查找):

class Solution {
    public int mySqrt(int x) {
        long left = 0;
        long right = x/2+1;
        while(left < right)
        {
            long mid = (left+right)/2;
            long res = mid*mid;
            if(res > x)
            {
                right = mid-1;
                res = right*right;
                if(res < x)
                    return (int)right;
            }
            else if(res < x)
            {
                left = mid+1;
                res = left*left;
                if(res > x)
                    return (int)mid;
            }
            else if(res == x)
                return (int)mid;
        }
        return (int)left;
    }
}

思路二(牛顿迭代法)

class Solution {
    public int mySqrt(int x) {
        final double EXP = 1e-2;
        double last = 0;
        double next = x;
        
        while(Math.abs(last-next) > EXP)
        {
        	last = next;
        	next = 0.5*(next+x/next);
        }
        return (int)next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值