防止Python迭代过程中使用的值的反转

时间:2017-05-06 17:45:26

标签: python arrays algorithm

我给出了一个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忽略相反的情况?

4 个答案:

答案 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)]