【牛顿迭代法&欧几里得算法】

文章目录

  • 牛顿迭代法之开平方根
    • 牛顿迭代法的简单介绍
  • 欧几里得之最大公约数

牛顿迭代法之开平方根

leetcode有一道求开平方根的算法题,于是我想用牛顿迭代法来求解。

牛顿迭代法的简单介绍

设r是f(x) = 0的根,现在选取x0 作为r的初始近似值,过点(x0, f(x0))做曲线y = f(x)的切线L,L : y=f(x0f(x0)(x-x0)) ,则L与X轴交点的横坐标X1 = x0 - f(x0/f(x0)),称x1为r的一次近似值。过点(x1, f(x1))做曲线y=f(x)的切线,并求该切线与x轴交点的横坐标x2 = x1 - f(x1/f(x1)),称x2为r的二次近似值。重复以上过程,得r的近似值序列,其中xn+1 = xn - f(xn/f(xn))称为r的n+1次近似值,这就是牛顿迭代公式。

现在我们来看下算法题:
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only integer part ofthe result is returned
Example 1:
Input: 4
Output: 2
Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842…, and since
the decimal part is truncated, 2 is returned.

根据牛顿迭代法,我们先求出这道题的迭代公式,假如我们求a的平方根x,则有f(x) = x2 - a
推导出该题的牛顿迭代式为 : xn+1 = 1/2(xn+a/xn)
得到了每次需要迭代的公式,就可以写算法了:

int mySqrt(int x)
{
    if (x < 0)
    {
        return -1;
    }
    double e = 1e-15;
    double xn = x;
    double xn1 = (xn + x / xn) / 2;
    while (abs(xn - xn1) > e)
    {
        xn = xn1;
        xn1 = (xn + x / xn) / 2;
    }
    return (int)xn;
}

欧几里得之最大公约数

欧几里得算法又叫辗转相除法,用来求两个数的最大公约数。
定理:
两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数.最大公约数(Greatest Common Divisor)
缩写为GCD, gcd(a,b) = gcd(b,a mod b) (不妨设a>b 且r=a mod b ,r不为0)
下面是证明定理的过程:
a可以表示成a = kb + r(a,b,k,r皆为正整数,且r
假设d是a,b的一个公约数,记作d|a,d|b,即a和b都可以被d整除。
而r = a - kb,两边同时除以d,r/d=a/d-kb/d=m,由等式右边可知m为整数,因此d|r
因此d也是b,a mod b的公约数
假设d是b,a mod b的公约数, 则d|b,d|(a-k*b),k是一个整数。
进而d|a.因此d也是a,b的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证。
因此,求最大公约数的代码为:

int GCD(int a, int b)
{
    if (a < b)
    {
        std::swap(a, b);
    }
    if (b == 0)
    {
        return a;
    }
    int iterValue = 0;
    while(b > 0)
    {
        iterValue = a % b;
        a = b
        b = iterValue;
    }
    return a;
}

你可能感兴趣的:(C++,数据结构与算法)