447 回旋镖的数量。我自己写的代码如下,时间1100ms左右。
def numberOfBoomerangs(self, points: List[List[int]]) -> int:
from collections import defaultdict
rlt = 0
for p1 in points:
dic = defaultdict(int)
for p2 in points:
d = (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2
dic[d] += 1
for v in dic.values():
if v > 1:
rlt += v * (v - 1)
return rlt
下面的代码是用时排名中,最快的示例,时间350ms左右。
def numberOfBoomerangs(self, points: List[List[int]]) -> int:
rlt = 0
for x1, y1 in points:
dic = {}
for x2, y2 in points:
dx = x1 - x2
dy = y1 - y2
d = dx*dx + dy*dy
if d in dic:
rlt += dic[d]
dic[d] += 1
else:
dic[d] = 1
return rlt*2
本来我以为区别在最后对dic.values()多循环遍历了一次,改完后发现并没有太多区别,只提高了一点点,930ms左右(这里提高的时间,我觉得应该是来自于下面第(2)问)
(1)经过我反复实验,最后发现,关键点在d的计算上,时间上:d = (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2 远大于 d = (p1[0] - p2[0])×(p1[0] - p2[0]) + (p1[1] - p2[1])×(p1[1] - p2[1]) 大于 d = dxdx + dydy(已分别计算出dx,dy)。这是什么原因呢?
另外,使用defaultdict,dict(),dic={}没有太大区别。
(2)在使用defaultdict下,最后的代码可以简写为如下形式。我发现简写后的代码,比引号内的代码慢150-200ms左右。
"""
if d in dic:
rlt += dic[d]
dic[d] += 1
else:
dic[d] = 1
"""
# 简写之后
if d in dic:
rlt += dic[d]
dic[d] += 1