本题代码:https://github.com/doubleZ0108/Leetcode/blob/master/69.x-%E7%9A%84%E5%B9%B3%E6%96%B9%E6%A0%B9.py
【牛顿迭代法】
平方根相当于求解 x 2 = n ⟺ f ( x ) = x 2 − n x^2 = n \iff f(x) = x^2-n x2=n⟺f(x)=x2−n的解,牛顿迭代法从一个很大的数开始,不断做函数切线,取切线于x轴交点不断迭代
x i x_i xi处的切线方程 f ( x i ) + f ′ ( x i ) ( x − x i ) = 0 f(x_i) + f'(x_i)(x-x_i) = 0 f(xi)+f′(xi)(x−xi)=0
解方程得 x = x i 2 + n 2 x i x = \frac{x_i^2 + n}{2x_i} x=2xixi2+n
终止条件是 x , x i x, x_i x,xi足够近,对于整数问题就是判断这两个数是不是差了1
或者可以通过泰勒函数展开来求近似解,本质是一样的
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
if x < 2: # 0, 1
return x
# 解法2
t = x
while t > x//t:
t = (t**2 + x) // (2*t)
return t
def otherSolution(self, x):
if x < 2:
return x
# 解法1: 直接顺序解会爆内存
for i in range(1, x//2+1):
if i*i <= x and (i+1)*(i+1) > x:
return i
# 解法1 改进
i, j = 1, x//2+1
while i<=j:
mid = (i+j)//2
if mid**2 <= x:
i = mid + 1
else:
j = mid - 1
return (i+j)//2
# 标准的牛顿法
root = x/2
for _ in range(20): # 迭代20次
root = (1/2) * (root + (x/root))
return root