图解牛顿迭代法(力扣题实战)

300 阅读2分钟

​​​本文已参与「新人创作礼」活动,一起开启掘金创作之路

一、题目描述

在这里插入图片描述> 🚥【问题分析】   这个问题有很多处理方法, 比如暴力枚举法,二分查找法。但今天介绍一个大家可能没有接触过的方法——牛顿迭代法。牛顿迭代法是求方程根的一种方法,其基本的思想就是:切线是曲线的线性逼近。通过这样不断的逼近,我们最终可以得出方程的解。  大家千万不要被牛顿的大名给吓到了,今天所讲的内容只要学过导数和三角函数就是有手就行。

二、方法介绍

①方法介绍 B是方程的零点,我们取零点附近一点A,过点A做曲线的切线与X轴交于D点。过点D做x轴的垂线,得到与曲线的交点E在这里插入图片描述 我们继续过点E做曲线的切线,通过不断重复上述过程,最终使得切线与x轴的交点不断接近与零点。我们由此就可以得出零点的近似解。在这里插入图片描述 是不是很简单,那我们继续往下看。 ②递推关系式 我们可以从三角函数入手,以α角为例,我们可以得出以下的关系式: 在这里插入图片描述 ③迭代结束的判断 不断迭代的过程中,x是不断趋向于零点的,同时“Xc”也是和“Xd”也是不断接近的,当Xc-Xd < 1E-6时,我们可以近似的认为此时Xc就等于零点值。 ④牛顿迭代法的局限 当然牛顿迭代法也不是万能的,仅举以下几个例子:参考文章

1.对于这种凸函数反而越切越远在这里插入图片描述 2.初始点选择不恰当,导致最终得出的解不是我们的目标解在这里插入图片描述 3.陷入循环震荡之中在这里插入图片描述 我们也不做什么具体的数学总结,大家在使用牛顿迭代法时首先预画图观察能否不断逼近零点。我想这样就能处理很多的问题了。接下来我们回到力扣题。

三、代码实现

int mySqrt(int num)
{
    if(num == 0)
        return 0;
    double x0 = (double)num;
    while(1)
    {
        double x1 = x0 / 2 +  num / x0 / 2;
        if(x0 - x1 < 1E-7)
            break;
        x0 = x1;
    }
    return (int)x0;
}

1.方程构建 由x ^ 2 = num我们可以构造出方程 f(x) = x^2 - num。转化为牛顿迭代法求零点问题 2. 初始点的选择 以num作为我们的初始点,经画图检验后一定会不断趋近于零点。 3.迭代关系式 从下图中我们可以看出 f(X0) / (x0 - X1) = f'(X0); 在这里插入图片描述 4.迭代结束的标志 当x0不断接近零点时,x0和x1也是不断接近的。当x0 - x1 < 1E-7时可以近似认为得到零点。 在这里插入图片描述 5.时间复杂度分析: (证明过程来源Leetcode) 在这里插入图片描述 所以对于这道题目而言,这是一个logn时间复杂度的算法

四、课后练习

题目传送链接 在这里插入图片描述