我的代码:
n = 3
a1 = 0
b1 = 10
a2 = 2
b2 = 2
if b1>n:
b1=n
if b2>n:
b2=n
diap1 = [x for x in range(a1, b1+1)]
diap2 = [x for x in range(a2, b2+1)]
def pairs(d1, d2, n):
res = 0
same = 0
sl1 = sorted(d1)
sl2 = sorted(d2)
for i in sl1:
for j in sl2:
if i+j==n and i!=j:
res+=1
elif i+j==n and i==j:
same+=1
return(res+same)
result = pairs(diap1, diap2, n)
print(result)
注意: n,a1,b1,a2,b2 可以更改。代码应该从2个列表中找到2个数字(每个1个),总和等于n。例如:对(a,b)和(b,a)不同但是(a,a)和(a,a)是同一对。因此,我的代码输出是正确的,对于上面的代码是1(1,2),但对于大输入,它需要太多时间。如何优化它以更快地工作?
答案 0 :(得分:4)
使用set()进行快速查找...
setd2 = set(d2)
不要尝试所有可能的数字对。一旦你修复了第一个列表中的数字,比如i,只要看看(n-i)是否在第二个列表中。
for i in sl1:
if (n-i) in setd2:
# found match
else:
# no match in setd2 for i
答案 1 :(得分:1)
通过以下方式,您可以最快地工作,找到总和等于n的两个数字,并将它们存储在元组列表中。
s1 = set(list1)
s2 = set(list2)
nums = []
for item in s1:
if n-item in s2:
nums.append((item, n-item))
答案 2 :(得分:1)
接受的答案非常容易理解和实施,但我只需要分享这种方法。您可以看到您的问题与此one相同 这个answer特别有趣,因为插入集合不需要额外的空间。我在答案中包含了算法。
如果对数组进行了排序,则可以在线性时间和常量存储中进行排序。
如果数组最初未排序,那么您可以先对它们进行排序,然后使用上述算法。
答案 3 :(得分:1)
感谢您明确定义问题并提供代码 您尝试优化的示例。
利用问题和表示法中的两个关键定义 提供,我限制我的优化尝试使用列表,并添加 能够随机改变与n,a1,b1,a2和a相关的值 B2。
为了显示优化结果,我创建了一个包含的模块 使用random.randit函数创建各种列表大小和 timeit.Timer函数用于捕获原始pair()函数所花费的时间以及在pairs2()函数中建议的优化。
在pairs2()函数中,您将注意到每个迭代循环包含一个 休息声明。这些消除了每个列表一次的不必要的迭代 满足所需的标准。你应该注意到列表的大小 增长,对2()与对()时间有所改善。
测试模块代码:
import random
from timeit import Timer
max_value = 10000
n = random.randint(1, max_value)
a1 = random.randint(0, max_value)
b1 = random.randint(1, max_value+1)
a2 = random.randint(0, max_value)
b2 = random.randint(1, max_value+1)
if b1>n:
b1=n
if b2>n:
b2=n
if a1>=b1:
a1 = random.randint(0, b1-1)
if a2>=b2:
a2 = random.randint(0, b2-1)
diap1 = [x for x in range(a1, b1)]
diap2 = [x for x in range(a2, b2)]
print("Length diap1 =", len(diap1))
print("Length diap2 =", len(diap2))
def pairs(d1, d2, n):
res = 0
same = 0
sl1 = sorted(d1)
sl2 = sorted(d2)
for i in sl1:
for j in sl2:
if i+j==n and i!=j:
res+=1
elif i+j==n and i==j:
same+=1
return(res+same)
def pairs2(d1, d2, n):
res = 0
same = 0
sl1 = sorted(d1)
sl2 = sorted(d2)
for i in sl1:
for j in sl2:
if i+j==n and i!=j:
res+=1
break
elif i+j==n and i==j:
same+=1
break
if res+same>0:
break
return(res+same)
if __name__ == "__main__":
result=0
timer = Timer("result = pairs(diap1, diap2, n)",
"from __main__ import diap1, diap2, n, pairs")
print("pairs_time = ", timer.timeit(number=1), "result =", result)
result=0
timer = Timer("result = pairs2(diap1, diap2, n)",
"from __main__ import diap1, diap2, n, pairs2")
print("pairs2_time = ", timer.timeit(number=1), "result =", result)
答案 4 :(得分:0)
如果从第一个列表中提取值n,然后在第二个列表中搜索值m以使总和与搜索到的值匹配,则可以制作一些快捷方式。例如,如果总和较小,则第二个列表中小于或等于m的所有值也不会给出正确的总和。同样,如果总和更大。
使用此信息,我将使用以下步骤:
请注意,使用堆是对两个序列进行分类排序的优化。但是,如果您经常遇到无匹配的情况,则在算法之前对数字进行排序可能是一种更快的方法。这样做的原因是一个好的排序算法将胜过通过堆的隐式排序,而不是通过渐近复杂度而是通过一些常数因子。