牛顿迭代法(Newton’s method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。
既然牛顿迭代法可以用来求解方程的根,那么不妨以方程 x2=nx2=n 为例,来试着求解它的根。为此。令f(x)=x2−nf(x)=x2−n, 也就是相当于求解 f(x)=0f(x)=0 的解,如上图所示。
首先随便找一个初始值 x0x0,如果 x0x0不是解,做一个经过 (x0,f(x0))(x0,f(x0)) 这个点的切线,与xx轴的交点为x1x1。同样的道理,如果 x1x1不是解,做一个经过(x1,f(x1))(x1,f(x1))这个点的切线,与xx轴的交点为x2x2。 以此类推。以这样的方式得到的xixi会无限趋近于 f(x)=0f(x)=0 的解。
判断xixi是否是f(x)=0f(x)=0的解有两种方法: 一是直接计算f(xi)f(xi)的值判断是否为00,二是判断前后两个解xixi和xi−1xi−1是否无限接近。
经过(xi,f(xi))(xi,f(xi))这个点的切线方程为
其中,f′(x)f′(x)为f(x)f(x)的导数,本题中为2x2x。令切线方程等于 00,即可求出
继续化简
基于上述迭代公式,我们其实给出了一个求平方根的算法。事实上,这也的确是很多语言中内置的开平方函数的实现方法。
Leetcode上也有一道经典面试题目涉及到开平方函数的实现,如下
基于我们已经给出的牛顿迭代法,下面就可来编程解决该问题了,示例代码如下
class Solution {
public:
int mySqrt(int x) {
if (x ==0)
return 0;
double pre;
double cur = 1;
do
{
pre = cur;
cur = x / (2 * pre) + pre / 2.0;
} while (abs(cur - pre) > 0.00001);
return int(cur);
}
};