我正在this problem上做HackerRank。我不是专门寻找更好地解决问题的方法,尽管当然欢迎这些方法(我想知道这里是否使用了yield
关键字,或者是否可以我可以动态地将range()
与y * y
进行比较的部分)。
我真正好奇的是,为什么我解决问题的一种方法可以缓解很多超时,并且我认为这与in
关键字与range
一起使用的方式有关-我我猜它不只是运行一个循环并比较所有元素吗?
导致所有超时的代码:
def squares(a, b):
max_square = int(math.sqrt(b) // 1)
min_square = int(math.sqrt(a) // 1)
counter = 0
for n in range(a, b + 1):
for y in range(min_square, max_square + 1):
if y * y == n:
counter += 1
return counter
缓解一次超时的所有代码:
def squares(a, b):
max_square = int(math.sqrt(b) // 1)
min_square = int(math.sqrt(a) // 1)
counter = 0
for y in range(min_square, max_square + 1):
if (y * y) in range(a, b + 1):
counter += 1
return counter
在reading a bit about ranges之后,我决定尝试使用此代码,从而减轻了所有超时。我认为这是因为范围类似于列表和生成器的混合,通过创建一次范围并将其保存为列表,我能够减轻对if
的每次检查时范围的重新创建吗?坦率地说,有了这样的简单函数,Python每次运行都会重新生成相同的范围,而不是引用同一对象。可能我在这里想念什么?
def squares(a, b):
max_square = int(math.sqrt(b) // 1)
min_square = int(math.sqrt(a) // 1)
counter = 0
the_range_list = list(range(min_square, max_square + 1))
for y in the_range_list:
if (y * y) in range(a, b + 1):
counter += 1
return counter
我不知道如何进行基准测试,所以如果有人可以告诉我实际的时差,那将很酷。但是我真的想知道:为什么第二个版本显然要快得多?
测试用例:
print(squares(35, 70))
>>> 3
print(squares(100, 1000))
>>> 22
print(squares(3, 9))
>>> 2
print(squares(17, 24))
>>> 0