我给出了一个n个整数和一个数字k的数组。我发现数组中是否有一对元素总和恰好是k。例如,给定数组[1,3,7]和k = 8,答案是肯定的,但是给定k = 6,答案是否定的。
我的第一次尝试是使用蛮力方法。我有一个不错的算法,可以完成工作而不用担心效率。
arr = [1,3,7]
for i in range(len(arr)):
for a in range(len(arr)):
if i != a:
if arr[i] + arr[a] == 8:
print('{} and {} is: yes'.format(arr[i], arr[a]))
elif arr[i] + arr[a] == 6:
print('{} and {} is: no'.format(arr[i], arr[a]))
这输出以下内容:
1 and 7 is: yes
7 and 1 is: yes
显然我不希望显示逆案例arr[0] + arr[2] and arr[2] + arr[0]
。我尝试在输出循环中使用数组pop和del for arr[i
]。
如何告诉python忽略相反的情况?
答案 0 :(得分:1)
你可以改变:
for a in range(len(arr)):
到
for a in range(i+1,len(arr)):
这将仅在i< a arr [0] + arr [2]会被找到,但它不会尝试相反的情况。
更快的方法是将每个项目添加到一个集合中,并查看集合中是否存在8-arr [i]。这将是O(n)而不是O(n ^ 2)
答案 1 :(得分:0)
最简单的方法是确保第二个元素始终位于列表中,而不是第一个元素。此外,如果您有一个列表,则可以循环遍历元素,而不是它们的索引。
arr = [1,3,7]
for i, first in enumerate(arr):
for second in arr[i+1:]:
if first + second == 8:
print('{} and {} is: yes'.format(first, second))
答案 2 :(得分:0)
如何使用'任何'?
a = [1,3,7]
if any(v+w == 8 and i != j for i,v in enumerate(a) for j,w in enumerate(a)):
print "yes"
答案 3 :(得分:0)
这是一个很好的用例。请记住,a + b == n< - > a == n-b。
检查集合中的成员资格是O(1)。因此,我们可以通过迭代中的两次迭代来解决这个问题。一个是创建集合,另一个是检查我们的合作伙伴'。我们可以确保只按照正确的顺序返回我们的对。确保我们的第一个项目小于目标// 2
def gen_pairs(iterable, target):
iterable = set(iterable)
for i in iterable:
if target-i in iterable and i <= target // 2:
yield i, target-i
这是一个简短的例子:
arr = [1,3,7,5]
print(list(gen_pairs(arr, 8)))
输出:[(1, 7), (3, 5)]
请注意以下(故意)错误。为什么会这样?你会如何解决这个问题? (提示 - collections.Counter是你的朋友!)
arr2 = [4, 1, 7]
print(list(gen_pairs(arr2, 8)))
[(1, 7), (4, 4)]