我正在编码一个问题的解决方案,其中代码将在给定列表a的情况下找到列表中的勾股三元组的数量。但是,当我将代码提交给自动分级机时,有一些测试案例使我的代码失败,但是我不知道出了什么问题。请帮助我指出我的错误.....
def Q3(a):
lst = [i ** 2 for i in a]
lst.sort()
ans = 0
for x in lst:
for y in lst:
if (x + y) in lst:
ans += 1
return ans // 2
“毕达哥拉斯三元组”是毕达哥拉斯定理的整数解,例如32 + 42 = 52。给定正整数列表,找到勾股三胞胎的数量。如果至少一个整数不同,则两个毕达哥拉斯三胞胎也将不同。
实施
·实现函数Q3(A),其中A是一个正整数列表。列表A的大小最大为250。
·列表A中没有重复项
·此函数返回勾股三胞胎的数量。
样品
·Q3([3,4,6,5])= 1
·Q3([4,5,6])= 0
答案 0 :(得分:1)
简单但不是非常有效的解决方案是在 3 个嵌套的 for 循环中循环遍历范围内的数字列表(例如,我取了 1 到 100 的数字),如下所示。但是对于100个元素会比较慢,需要100^3次操作
triplets = []
for base in range(1,101):
for height in range(1,101):
for hypotenuse in range(1,101):
# check if forms a triplet
if hypotenuse**2 == base**2 + height**2:
triplets.append(base, height, hypotenuse)
这可以稍微提高效率(有更好的解决方案) 通过计算每个底和高组合的斜边,然后检查斜边是否为整数
triplets = []
for base in range(1,101):
for height in range(1,101):
hypotenuse = math.sqrt(base**2 + height**2)
# check if hypotenuse is integer by ramiander division by 1
if hypotenuse%1==0:
triplets.append(base, height, hypotenuse)
# the above solution written a list comprehension
a = range(1,101)
[(i,j,math.sqrt(i*i+j*j)) for i in a for j in a if math.sqrt(i*i+j*j)%1==0]
如果您认为 (3,4,5) 和 (3,5,4) 不同,请使用集合而不是列表并最终获得 len(triplets_set)
答案 1 :(得分:-1)
问题1:假设您输入的是
[3,4,5,5,5]
尽管您的问题尚不清楚,但我的推测是这应该算作3个毕达哥拉斯三元组,每个都使用这3个5s中的一个。
您的函数只会返回1。
问题2:正如Sayse指出的那样,您的“三胞胎”可能试图两次使用相同的数字。
最好使用itertools.combinations
从正方形列表中获得不同的组合,并计算出现多少合适的三元组。
from itertools import combinations
def Q3(a):
squares = [i**2 for i in a]
squares.sort()
ans = 0
for x,y,z in combinations(squares, 3):
if x + y == z:
ans += 1
return ans
答案 2 :(得分:-1)
鉴于您现在通过编辑添加到问题中的输入约束,我认为您的实现在逻辑上没有任何问题。您的代码无法通过的唯一测试用例类型必须与性能相关,因为您正在使用最慢的解决方案之一,方法是使用3个嵌套循环在列表的整个范围内进行迭代(in
运算符本身是通过循环实现的。
由于列表已排序并且我们想要x < y < z
,因此我们应使y
从x + 1
开始,并使z
从y + 1
开始。并且由于给定了x
,所以x
的值取决于y
的值,对于每个给定的y
,我们可以递增z
直到{{1} }不再成立,如果此时z * z < x * x + y * y
,我们已经找到了毕达哥拉斯三元组。这允许z * z == x * x + y * y
和y
仅扫过z
之上的值一次,因此将时间复杂度从O(n ^ 3)降低到O(n ^ 2),从而使时间变得复杂列表大小为250时快40倍:
x