用于测试代码的网页在这里: https://leetcode.com/problems/sqrtx/description/
我提交了这些代码并通过:
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
if x==1:
return 1
lowest=0.0
uppest=x*1.0
count=1
middle=(lowest+uppest)*0.5
while (abs(middle*middle-x)>0.001) and (count<=10000):
if middle*middle>x:
uppest=middle
else:
lowest=middle
middle=(lowest+uppest)*0.5
count=count+1
return int(middle)
但是当我更改
时while (abs(middle*middle-x)>0.001) and (count<=10000):
进入
while (abs(middle*middle-x)>0.0001) and (count<=10000):
或添加更多的“ 0”(如0.00000000001),并使用“ 9”作为测试输入,这会出错 输出应为3,但我得到2
在使用对分法时如何解决此类问题? 我不想使用库(我知道使用库是最简单的方法,但我想了解更多信息)
答案 0 :(得分:2)
它更像是数学问题,而不是python,只需插入
print(middle,middle**2>x)
出于调试目的。
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
if x==1:
return 1
lowest=0.0
uppest=x*1.0
count=1
middle=(lowest+uppest)*0.5
while (abs(middle*middle-x)>0.0001) and (count<=10000):
if middle*middle>x:
uppest=middle
else:
lowest=middle
middle=(lowest+uppest)*0.5
count=count+1
print(middle,middle**2>x)
return int(middle)
sol=Solution()
print(sol.mySqrt(9))
输出
2.25 False
3.375 True
2.8125 False
3.09375 True
2.953125 False
3.0234375 True
2.98828125 False
3.005859375 True
2.9970703125 False
3.00146484375 True
2.999267578125 False
3.0003662109375 True
2.99981689453125 False
3.000091552734375 True
2.9999542236328125 False
3.0000228881835938 True
2.999988555908203 False
2
您已经知道原因了。
我也不知道为什么你不能只使用
round(middle)
答案 1 :(得分:2)
罪魁祸首是
return int(middle)
获得2的原因是因为您正在将诸如2.99998855591之类的数字强制转换为int,相当于floor(x)
经过n0次迭代后,目标值和中间值之间的误差sqrt(x) - middle
遵循阻尼振荡。
答案 2 :(得分:1)
查看其他答案以了解正在发生的事情。解决方案是:
return int(middle + 0.5)
四舍五入到最接近的整数。
当然,更大的问题是您在计算整数平方根时将中间值转换为浮点型。与Python整数相比,浮点数的范围非常有限。尝试这样的事情:
def int_sqrt(n):
"""Return integer square root of integer ``n``.
"""
x = n
y = (x + 1) >> 1
while y < x:
x = y
y = (x + n // x) >> 1
return x
,例如在int_sqrt(2**12345-1)
上运行它,它应该返回一个1858数字。