📜  整数的 sqrt (1)

📅  最后修改于: 2023-12-03 15:10:23.128000             🧑  作者: Mango

整数的 sqrt

在程序设计中,经常需要对整数作取平方根的操作。下面介绍几种求整数平方根的方法。

方法一:暴力枚举

暴力枚举从 0 开始,不断尝试算出 x 的平方,直到平方结果第一次大于等于 x。

def sqrt(x: int) -> int:
    i = 0
    while i * i <= x:
        i += 1
    return i - 1

时间复杂度为 O(√n)。当 x 很大时,算法表现不佳。

方法二:二分查找

由于整数的平方根一定落在 [0, x] 范围内,因此可以用二分查找来快速查找整数平方根。对于每一个 mid,比较 mid 的平方和 x 的大小关系。如果 mid 的平方小于 x,则在 [mid+1, end] 范围内继续查找;如果 mid 的平方大于等于 x,则在 [start, mid] 范围内继续查找。

def sqrt(x: int) -> int:
    if x == 0:
        return 0
    left, right = 1, x
    while left <= right:
        mid = (left + right) // 2
        if mid * mid <= x and (mid+1) * (mid+1) > x:
            return mid
        elif mid * mid > x:
            right = mid - 1
        else:
            left = mid + 1

时间复杂度为 O(log n)。这是一种效率比较高的方法。

方法三:牛顿迭代法

牛顿迭代法是一种求解方程的方法,可以用来求整数的平方根。它的思想是:假设已经有一个 x,使得它的平方与 x 的差值称为 f(x),那么就可以用一条过点 (x, f(x)) 的切线来逼近函数 y = x^2 - target 的零点。

具体来说,从任意一个正整数开始,不断迭代计算,直到达到足够的精度为止。具体的表达式为:

x = (x + a // x) // 2

其中,a 是待求解的整数,x 是上一次迭代的结果。迭代计算的停止条件可以是两次迭代结果的差值小于一个极小值。

def sqrt(x: int) -> int:
    if x == 0:
        return 0
    C, x0 = float(x), float(x)
    while True:
        xi = 0.5 * (x0 + C / x0)
        if abs(x0 - xi) < 1e-7:
            break
        x0 = xi
    return int(x0)

时间复杂度为 O(log n)。虽然迭代次数比二分查找多,但每次迭代都非常快,因此整体效率表现不错。