返回

巧解LeetCode-69:抽丝剥茧,探寻平方根的奥秘

后端

绪论:平方根的本质与应用

平方根,一个古老而神秘的概念,在数学、物理、工程等领域有着广泛的应用。它代表着一种开平方运算,即求出一个数的正平方根,即使其平方等于该数本身的值。例如,4的平方根是2,因为2的平方是4。

平方根的计算方法由来已久,古埃及人早在公元前1650年就已经掌握了计算平方根的方法。随着数学的发展,各种计算平方根的方法也层出不穷,其中牛顿迭代法和二分查找法最为常用。

一、牛顿迭代法:从无到有的逼近

牛顿迭代法,又称牛顿-拉夫逊法,是一种求解方程的数值方法。它的基本思想是:从一个初始值出发,不断地通过迭代计算来逼近方程的根。

将平方根的计算转化为方程求解后,牛顿迭代法的计算公式为:

x1 = x0 - f(x0) / f'(x0)

其中,x0是初始值,x1是迭代后的新值,f(x)是目标函数,f'(x)是目标函数的导数。

在计算平方根时,目标函数为f(x) = x^2 - n,其中n是待求平方根的数字。目标函数的导数为f'(x) = 2x。

def sqrt_newton(n, x0):
    """
    牛顿迭代法求平方根

    Args:
        n (int): 待求平方根的数字
        x0 (int): 初始值

    Returns:
        float: 平方根的近似值
    """
    while True:
        x1 = x0 - (x0**2 - n) / (2 * x0)
        if abs(x1 - x0) < 1e-6:
            break
        x0 = x1
    return x1


print(sqrt_newton(16, 4))  # 4.0
print(sqrt_newton(25, 5))  # 5.0
print(sqrt_newton(100, 10))  # 10.0

二、二分查找法:从范围到精确

二分查找法是一种在有序数组中查找元素的算法。它的基本思想是:将数组分成两半,比较待查找元素与中间元素的大小,然后继续在较小或较大的那一半中查找,如此反复,直到找到待查找元素或数组为空。

在计算平方根时,二分查找法的搜索范围为[0, n],其中n是待求平方根的数字。在每一步中,算法计算中间元素x,并比较x^2与n的大小。如果x^2大于n,则搜索范围变为[0, x-1];如果x^2小于n,则搜索范围变为[x+1, n]。

def sqrt_binary_search(n):
    """
    二分查找法求平方根

    Args:
        n (int): 待求平方根的数字

    Returns:
        float: 平方根的近似值
    """
    low = 0
    high = n
    while low <= high:
        mid = (low + high) // 2
        if mid**2 == n:
            return mid
        elif mid**2 < n:
            low = mid + 1
        else:
            high = mid - 1
    return (low + high) / 2


print(sqrt_binary_search(16))  # 4.0
print(sqrt_binary_search(25))  # 5.0
print(sqrt_binary_search(100))  # 10.0

三、算法比较与应用场景

牛顿迭代法和二分查找法都是求解平方根的有效算法,但各有优缺点。

牛顿迭代法收敛速度快,但需要计算导数,在某些情况下可能难以实现。二分查找法不需要计算导数,实现简单,但收敛速度较慢。

在实际应用中,如果精度要求不高,或者待求平方根的数字很大,可以使用二分查找法。如果精度要求很高,或者待求平方根的数字很小,可以使用牛顿迭代法。

结语:算法之美,在于巧思

平方根的计算看似简单,但蕴藏着算法的智慧。牛顿迭代法和二分查找法两种算法,从不同的角度切入,殊途同归,都为我们提供了计算平方根的有效方法。

算法之美,在于巧思。算法的本质,是将复杂的问题分解成简单的问题,然后一步一步地解决。这不仅是算法的精髓,也是一种思维方式,值得我们学习和借鉴。