📅  最后修改于: 2023-12-03 15:10:23.128000             🧑  作者: Mango
在程序设计中,经常需要对整数作取平方根的操作。下面介绍几种求整数平方根的方法。
暴力枚举从 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)。虽然迭代次数比二分查找多,但每次迭代都非常快,因此整体效率表现不错。