LeetCode 69. Sqrt(x) 解题报告

LeetCode 69. Sqrt(x) 解题报告

题目描述

Implement int sqrt(int x).

Compute and return the square root of x.


示例

没有给出。


限制条件

没有明确给出。


解题思路

这道题很虐心,我首先用的是牛顿迭代法解题,但是一直在2147395600和214739599这两个数出问题,于是改成用二分法,然而,还是载在这两个数据上,通过艰苦卓绝地debug调试才终于过了,下面分别讲解这两种解法,并贴出AC的代码。

二分法:
二分法就是不断更新结果所属的上界和下界来逼近结果,比如求9的平方根,一开始设置结果的界限为[0, 9],中间点取整后是4( (0+9)÷2=4 ),因为 42=16>9 ,表示上界可以更新为4,此时界限为[0, 4],中间点取整后2( (0+4)÷2=2 ),因为 22=4<9 ,证明下界可以更新为2,所以界限为[2,4],不断重复上述步骤,最后会得到接近或等于9的平方根的结果。

具体实现中需要根据题目调整参数,比如数据类型需要为long long,循环的结束条件是low > high以及返回的是(low + high) / 2。请见下面代码1.

牛顿迭代法:
牛顿迭代法同样是通过迭代来逼近结果的解法。它将求平方根的问题转化为求 f(x)=x2aax ,显而易见, x=a 就是其中一个解。对 f(x) 求导,得到 f(x)=2x ,表明 f(x)线线2x

接下来结合下图对迭代过程进行讲解:

牛顿迭代法

首先假设一个解为 xi ,对应的就是 f(xi) ,当然这个解不是结果,所以需要寻找下一个更靠近结果的点 xi+1 ,而寻找 xi+1 的一个简单方法就是在 (xi,f(xi)) 处作切线,取切线与 x 轴的交点。
由于(xi,f(xi))(xi+1,0))均位于斜率为 2xi 的切线上,所以通过 0f(xi)xi+1xi=2xi 得到

xi+1=xi+f(xi)2xi=xi+xi2+a2xi=xi2+a2xi

上式得到就是递推的公式,不断使用该公式得到 x 直到x2小于等于 a <script type="math/tex" id="MathJax-Element-7354">a</script>。

下面贴出来的牛顿迭代法代码是大神的解答代码,真是简洁优雅。


代码

二分法

class Solution {
public:
    int mySqrt(int x) {
        if (x < 2)
            return x;

        long long low = 0, high = x, result = 0;

        while(high >= low) {
            result = (low + high) / 2;

            if (result * result > x)
                high = result - 1;
            else if (result * result < x)
                low = result + 1;
            else
                break;
        }

        return (low + high) / 2;
    }
};

牛顿迭代法

class Solution {
public:
    int mySqrt(int x) {
        long r = x;

        while (r * r > x)
            r = (r + x / r) / 2;

        return r;
    }
};

总结

这道题花了很长时间,以前我不知道求平方根有二分法和牛顿迭代法,所以花了时间去理解这两种算法,原理很容易理解,但是实现时却出现了各种问题,需要耐心调试。
通过这道题我学会了牛顿迭代法,并知道了二分法的另一个应用,感觉收获很大,下周继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值