前言
前几天刷题时候看到一道题,就是不用任何内置函数与库,实现算一个数的根,第一反应就是二分法,后面在一众评论和题解中发现一个方法,叫做牛顿迭代,还蛮有意思的,下面,我们就一起来看一下牛爵爷的方法。
牛顿迭代解释
牛顿 迭代法 (Newton’s method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是 牛顿 在17世纪提出的一种在 实数 域和 复数 域上近似求解方程的方法。 多数方程不存在求根公式,因此求精确根非常困难,甚至不可解,从而寻找方程的近似根就显得特别重要。 方法使用函数 的 泰勒级数 的前面几项来寻找方程 的根。 牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程 的单根附近具有平方收敛,而且该法还可以用来求方程的重根、复根,此时线性收敛,但是可通过一些方法变成 超线性收敛 。
这是网上的解释,说实话,我觉得这个说来就算我再看十遍也看不明白。于是我花了时间找了很多博主写的文章与代码,总算对这个东西有了个浅显的理解(奈何笔者高数成绩不怎么样,无法像网上众多大佬一样对其进行化简)
牛顿迭代原理
牛顿迭代方程:x(n+1)=xn - f(xn)/f’(xn)
如图所述,实际上就是根据一个初始点做切线,找到该切线与X轴的交点,找到下一个点的坐标,然后不断的迭代,直到找到误差最小的点为止。
(图片来源网络,侵删)
意思就是,你知道一个离根很近的X的坐标xn,并且知道该函数的导数,那么就可以找到下一个离根更近的点,这个点不是该方程的解,只是不断的靠近它,我们找到一定误差范围内的就行了。
力扣题
那么,说了那么多,跟我们的python算法有何关系呢?且让我们回到开头所说的题目上面,我们先看题:
力扣链接 除此题外,第367题也是:
python实现
那么就正式上代码:
#牛顿迭代
class Solution:
def mySqrt(self, x: int) -> int:
val=1
while True:
val=val-(val*val*val-x)/(3*val*val)
if val*val*val - x <0.0001:
break
val=int(val)
return val
我们先用立方根试试看:
print(Solution().mySqrt(27))
输出:
结果正常,那么就改成题目要的平方根,来解一下题:
#牛顿迭代
class Solution:
def mySqrt(self, x: int) -> int:
val=1
while True:
val=val-(val*val-x)/(2*val)
if val*val - x <0.0001:
break
val=int(val)
return val
结果也还行,也算实现了一题多解(自我安慰一下)。
附(二分法解此题(力扣367))
class Solution:
def isPerfectSquare(self, num: int) -> bool:
left ,right = 0, num
while right >= left:
mid=(left+right)//2
sq=mid*mid
if sq == num:
return True
if sq > num:
right=mid - 1
else:
left=mid + 1
return False
二分法结果如下:
算法初学者,小白一枚,如有纰漏的地方,希望评论斧正,感激不尽。