美文网首页
LeetCode 第 69 题:使用牛顿法求解平方根

LeetCode 第 69 题:使用牛顿法求解平方根

作者: 李威威 | 来源:发表于2019-05-29 23:26 被阅读0次

    传送门:69. x 的平方根

    实现 int sqrt(int x) 函数。

    计算并返回 x 的平方根,其中 x 是非负整数。

    由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

    示例 1:

    输入: 4
    输出: 2
    

    示例 2:

    输入: 8
    输出: 2
    说明: 8 的平方根是 2.82842..., 
         由于返回类型是整数,小数部分将被舍去。
    

    二分法

    思路:使用二分查找,特别注意:应该返回右边端点。

    Python 代码1:

    class Solution:
        # 二分法
        def mySqrt(self, x):
            """
            :type x: int
            :rtype: int
            """
            l = 0
            r = x // 2 + 1
            while l <= r:
                m = l + (r - l) // 2
                s = m * m
                if s == x:
                    return m
                elif s < x:
                    l = m + 1
                else:
                    r = m - 1
            # 注意返回 l 和返回 r 的区别,应该返回 r
            # 【因为返回的是不超过,所要把右边界返回回去】
            return r
    

    Python 代码2:

    class Solution:
        # 二分法
        def mySqrt(self, x):
            """
            :type x: int
            :rtype: int
            """
            if x == 1:
                return 1
            l = 0
            r = x // 2
            while l <= r:
                m = l + (r - l) // 2
                s = m * m
                if s == x:
                    return m
                elif s < x:
                    l = m + 1
                else:
                    r = m - 1
            return r
    

    牛顿法

    思路:使用牛顿法,推荐这种做法,更简单,返回值向下取整,就能符合题要求。

    牛顿法的公式推导必须要会。

    Python 代码:

    class Solution:
        # 牛顿法
        # 与系统函数作比较
    
        def mySqrt(self, x):
            """
            :type x: int
            :rtype: int
            """
            if x < 0:
                raise Exception('不能输入负数')
            if x == 0:
                return 0
    
            cur = 1
            while True:
                pre = cur
                cur = (cur + x / cur) / 2
                if abs(cur - pre) < 1e-6:
                    return cur
    
        # 这个解提交到 LeetCode 上就可以了
        def mySqrt1(self, x):
            """
            :type x: int
            :rtype: int
            """
            if x < 0:
                raise Exception('不能输入负数')
            if x == 0:
                return 0
            # 起始的时候在 1 ,这可以比较随意设置
            cur = 1
            while True:
                pre = cur
                cur = (cur + x / cur) / 2
                if abs(cur - pre) < 1e-6:
                    return int(cur)
    
    
    if __name__ == '__main__':
        import numpy as np
    
        nums = np.linspace(0, 999, 100)
        solution = Solution()
        for num in nums:
            a = solution.mySqrt(num)
            b = np.sqrt(num)
            print("牛顿法:{} \t NumPy:{}\t 差距:{}".format(a, b, a - b))
    
    

    下面是牛顿法的笔记:

    image-20190110160239961 image-20190110160310951

    [图片上传失败...(image-b7244b-1559143685477)]

    image

    参考资料

    牛顿法的应用之一:解方程,求开方。

    马同学的《如何通俗易懂地讲解牛顿迭代法求开方?》讲解了牛顿法迭代求高次方程的根的思路:
    https://www.zhihu.com/question/20690553

    注明:为什么例子是二次的呢?因为二次一定是凸函数。

    皮果提的文章

    牛顿法与拟牛顿法学习笔记(一)牛顿法
    http://blog.csdn.net/itplus/article/details/21896453

    牛顿法与拟牛顿法学习笔记(二)拟牛顿条件
    http://blog.csdn.net/itplus/article/details/21896619

    牛顿法与拟牛顿法学习笔记(三)DFP 算法
    http://blog.csdn.net/itplus/article/details/21896981

    牛顿法与拟牛顿法学习笔记(四)BFGS 算法
    http://blog.csdn.net/itplus/article/details/21897443

    (本节完)

    相关文章

      网友评论

          本文标题:LeetCode 第 69 题:使用牛顿法求解平方根

          本文链接:https://www.haomeiwen.com/subject/vulptctx.html