完成函数 int sqrt(int x)。
计算并返回 x 的平方根,其中 x 是一个非负整数。
返回结果去掉小数,只保留整数。
示例:
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.
思路
1、枚举法
让 i 从 0 到 x 依次遍历,每次遍历时判断 i 的平方与 x 的大小,找到平方值小于等于 x 的最大的 i。
缺点:
当 x 很大时,遍历次数较多。
2、二分查找法
使用二分法的思路,定义一个上界 u 和下界 l,每次遍历时判断上下界的中位数 mid 的平方与 x 的大小,进而更新上界或下界,继续遍历。
可以使用递归法来实现二分查找,递归结束条件为:上下界相差不超过 1。
3、牛顿逼近法
使用数学中的最优化方法:牛顿逼近法,来将其变为一个求解方程的问题。
牛顿逼近法:
要想寻找 f ( y ) = 0 f(y)=0 f(y)=0 的解,则可以使用迭代公式: y : = y − f ( y ) f ′ ( y ) y := y - \frac{f(y)}{f'(y)} y:=y−f′(y)f(y),直至收敛。
应用到本题,则为:已知 f ( y ) = y 2 − x f(y) = y^2 - x f(y)=y2−x,求使得 f ( y ) = 0 f(y) = 0 f(y)=0 的 y y y 值。
其中, f ′ ( y ) = 2 y f'(y) = 2y f′(y)=2y,因此迭代公式为 y : = y − y 2 − x 2 y = y 2 + x 2 y y := y - \frac{y^2-x}{2y} = \frac y 2 + \frac{x}{2y} y:=y−2yy2−x=2y+2yx
收敛条件: f ( y ) f(y) f(y) 的结果与 0 的距离小于某个阈值,如 0.1。
python实现
def mySqrt(x):
"""
:type x: int
:rtype: int
枚举法
"""
if x <= 1:
return x
for i in range(x+1):
if i * i > x:
break
return i-1
def mySqrt2(x):
"""
:type x: int
:rtype: int
牛顿逼近法.
"""
y = x
while (y*y - x) > 0.1:
y = y/2 + x / (2*y)
print(y)
y = int(y)
if (y+1)**2 < x: # 可能y=3.9999但是真实结果为4.0001,因此需要判断最后结果是 y 还是 y+1。
return y+1
else:
return y
def mySqrt3(x):
'''
二分查找法
'''
if x <= 1:
return x
def binary_search(x, l, u):
'''
递归查找x的开方值。
'''
if u - l <= 1:
return l
mid = (u+l)//2
if mid**2 == x:
return mid
elif mid**2 > x:
return binary_search(x, l, mid)
else:
return binary_search(x, mid, u)
return binary_search(x, 0, x)
if '__main__' == __name__:
x = 9
print(mySqrt3(x))