暴力循环已死,牛顿迭代法称王

你好,我是小黄,一名独角兽企业的Java开发工程师。
感谢茫茫人海中我们能够相遇,
俗话说:当你的才华和能力,不足以支撑你的梦想的时候,请静下心来学习,
希望优秀的你可以和我一起学习,一起努力,实现属于自己的梦想。

在这里插入图片描述

一、引言

今天在做力扣每日一题中,有一道题为:

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

进阶:不要 使用任何内置的库函数,如  sqrt 。

大名鼎鼎的求平方根,传说中的牛顿迭代法,本篇来看一下具体是怎么进行实现的吧!

二、牛顿迭代法

牛顿迭代法又称为牛顿-拉弗森方法,实际上是由牛顿、拉弗森(又是一个被牛顿大名掩盖的家伙)各自独立提出来的

牛顿-拉弗森方法提出来的思路就是 利用切线是曲线的线性 逼近这个思想。

牛顿、拉弗森们想啊,切线多简单啊,研究起来多容易啊,既然切线可以近似于曲线,我直接研究切线的根不就成了。

如图所示:

在这里插入图片描述

对于上述函数的根来说,我们知道:x = 0

如果用牛顿迭代法怎么进行计算呢?

  • F(x) = x * x
  • F'(x) = 2 * x

在这里插入图片描述

首先,牛顿迭代***找到一个点,比如 x0 ,从 x0 向曲线做直线,交于点 A,做点 A 的切线交于点 x1

这样的话,我们可以得到三个点:x1、x0、A

设A点坐标为 (x0,x0 * x0)、x1点坐标为 (x1, 0)

通过A点和x1点的坐标,可以得出该线的斜率:K = (x0 * x0) / (x0 - x1)

化简得知:

  • x0 - x1 = ( x0 * x0) / K
  • x0 - x1 = F(x0) / F'(x0)
  • x0 - x1 = x0 / 2
  • x1 = x0 / 2

我们再以 x1 点做上面相同的操作,得到:

  • x2 = x1 / 2

我们无限制的进行上述操作,最终会得到一个公式:Xn+1 = Xn / 2

当无线次的迭代时,我们的 x 值会趋于0

三、平方根

我们上面说到,对于 F(x) = x * x,最终得到的结果为:Xn+1 = Xn / 2

我们想,对于平方根来说:x * x = num

可不可以转化一下,比如:F(x) = x * x - numF'(x) = 2 * x,求这个函数的交点

利用上述我们说的牛顿迭代法,我们可以得知:

在这里插入图片描述

F1 点为(x0,x0 * x0 - num)x1 点为(x1,0)

则:

  • K = (x0 * x0 - num) / (x0 - x1)
  • x0 - x1 = (x0 * x0 - num) / K
  • x0 - x1 = F(x0) / F'(x0)
  • x0 - x1 = x0 / 2 - num / (2 * x0)
  • x1 = x0 / 2 + num / (2 * x0)

将x1、x2两点同样进行迭代,得到:x2 = x1 / 2 + num / (2 * x1)

得出式子:Xn+1 = Xn / 2 + num / 2 * Xn

简单来说,选中某个x的初始值,无限进行迭代,最终找到其平方根

F(x) = x * x - num 凸函数的性质,最终的结果应该是:x = sqrt(num)

我们最开始的 x 可以直接取值为 num,因为 num >= sqrt(num)

一般来说,可以判断相邻两次迭代的结果的差值是否小于一个极小的非负数,一般可以取 1e-6 或者 1e-7

四、代码实现

    public boolean isPerfectSquare(int num) {
        if(num == 1){
            return true;
        }
        double ans = num;
        double dir = num;
        while(ans * ans - dir >= 1e-6){
            ans = ans / 2 + dir / (2 * ans);
        }
        int x = (int)ans;
        return x * x == num;
    }

在这里插入图片描述

五、总结

简单来说,牛顿迭代法通过不断的进行迭代,逐渐趋近于某个目标值

题目一:367. 有效的完全平方数

有兴趣的小伙伴可以去做一下,目前来说对于这种 平方根 题目,面试官最想听到的就是 牛顿迭代法,反手给其一波推理过程,直接抬走面试官。

对源代码有兴趣的小伙伴,可以关注 爱敲代码的小黄 公众号,回复:算法源码 即可获得算法源码

本期的内容就到这里,下期将会讲述 最小生成树(Prim、Kruskal) 算法。

我是一名独角兽企业的Java开发工程师,希望可以点个关注呀,有问题可以留言或者私信加我微信,我们下期再见!

在这里插入图片描述

#学习路径#
全部评论

相关推荐

想润的芹菜人狠话不多:把其中一个老总放中间都会得罪另一个
点赞 评论 收藏
分享
10-25 00:32
香梨想要offer:感觉考研以后好好学 后面能乱杀,目前这简历有点难
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务