Python - 计算所有对的总和

时间:2017-09-16 18:30:31

标签: python sum

我最近有一个测试问题要求列出并计算给定列表中的所有对和,然后返回总和等于给定目标值的次数。

我编写了代码,并认为它当时是正确的,但它看起来像是两次对。我想弄清楚一种方法,以确保我不重复对数。

我显然没有正确地得到面试问题。我的想法是存储哪些指数已经汇总并跳过它们,如果有的话?

*对不必连续

myList = [1,4,6,7,8]

def getSums(myList,target):
    l_ = len(myList)
    sums = []
    for i in range(l_):
        for j in range(l_):
            if i==j:
                continue
            else:
                sums.append((myList[i],myList[j],myList[i]+myList[j]))
    return [x for x in sums if x[2]==target]

print getSums(myList,5)

5 个答案:

答案 0 :(得分:1)

在这里,我们模拟了itertools.combinations的淡化版本。

<强>代码

def combinations(iterable):
    """Return r=2 combinations of an iterable."""
    # Inherently, r=2 (pairs) by using two loops
    pool = []
    for idx_i, i in enumerate(iterable):
        for idx_j, j in enumerate(iterable):
            if (idx_i != idx_j) and ((j,i) not in pool):
                pool.append((i, j))
    return pool


def get_sums(iterable, target):
    """Return the tally of summed paired equal to the target value."""
    results = [sum(i) for i in combinations(lst)]
    return len([i for i in results if i == 5])


get_sums([1, 4, 6, 7, 8], 5)
# 1

<强>详情

让我们将问题分成3个步骤:

  1. 组合对(有一定限制)
    • 假设没有重复的索引,即idx_i != idx_j
    • 假设(lst[0], lst[1])(lst[1], lst[0])
    • 不同
  2. 过滤器对,其总和等于目标
  3. 计算过滤结果
  4. 选项

    如果允许,

    itertools肯定更好:

    import itertools as it
    
    lst, target = [1, 4, 6, 7, 8], 5
    results = [sum(i) for i in list(it.combinations(lst, 2))]
    len([i for i in results if i == target])
    # 1
    

    实际上,我从itertools解决方案开始并向后工作,清除基本逻辑,然后替换模块依赖。也许这是一种可以用来“重新发明轮子”的策略。

答案 1 :(得分:0)

我会使用类似的东西:

from collections import Counter
myList = [1,4,6,7,8]

c = Counter(myList)

sum([k for k,v in c.items() if v == 2])

修改了第一个例子(未经测试,只是逻辑示例):

myList = [1,4,6,7,8]

def getSums(myList,target):
    l_ = len(myList)
    sums = []
    for i in range(len(myList)):
        for item in myList[i:]:
            sums.append((myList[i],item,myList[i]+item))
    return [x for x in sums if x[2]==target]

print getSums(myList,5)

答案 2 :(得分:0)

作为一个面试问题,这是一个算法问题,所以这就是解决方案,你会发现它是许多算法书中的一个非常基本的问题。

myList = [1, 4, 6, 7, 8]


def getSums(myList, target):
    lst = sorted(myList)
    i = 0
    j = len(lst) - 1
    while i <= j:
        tmp = lst[i] + lst[j]
        if tmp > target:
            j -= 1
            continue
        elif tmp < target:
            j += 1
            continue
        else:
            return [lst[i], lst[j]]

    raise Exception('No available pair found')


print(getSums(myList, 5))

答案 3 :(得分:0)

我认为它是重复计算的,因为你要经历两次列表,一次是通过索引i,一次是通过索引j。

我得到以下代码以产生正确的结果。我添加了值3,以便我可以看到它是否会发现总和为10的所有对。

myList = [1,3,4,6,7,8]
target = 10

def getSums(myList,target):
    l_ = len(myList)
    sums = []
    for i in range(l_):
        for j in range(l_):
            if i!=j:
                if (myList[i] + myList[j]) == target:
                    if myList[i] not in sums:
                        sums.append(myList[i])
                        sums.append(myList[j])
    print sums



getSums(myList, target)

答案 4 :(得分:0)

你确定你必须计算所有对的总和吗?这是非常低效的,不是必需的。使用集合,您可以在一次通过中解决此问题,而无需外部库。

算法以这种方式工作:

  • 创建一个空集
  • 创建一个空列表
  • 遍历输入列表的每个元素:
    • 检查是否已看到target - element
      • 如果是,则找到一对新对象:将其添加到列表中
    • 标记element已经看到了。

以下是代码:

myList = [1,4,6,0,2,7,8,3,5]

def getSums(myList,target):
    already_seen = set()
    pairs = []
    for x in myList:
        if (target - x) in already_seen:
            pairs.append((x, target - x))
        already_seen.add(x)
    return pairs

print(getSums(myList,5))
# [(4, 1), (3, 2), (5, 0)]

此解决方案应适用于具有唯一元素的任何列表。该列表不需要排序。与其他解决方案的O(n)相比,复杂度为O(n**2)

如果元素不是唯一的,您可以使用Counter代替set

myList = [1,4,6,0,2,7,8,3,5]

from collections import Counter
def getSums(myList,target):
    already_seen = Counter()
    pairs = []
    for x in myList:
        for _ in range(already_seen[target - x]):
            pairs.append((x, target - x))
        already_seen[x] += 1
    return pairs

print(getSums(myList,5))
# [(4, 1), (3, 2), (5, 0)]
print(getSums([2, 2, 2],4))
# [(2, 2), (2, 2), (2, 2)]

最后的结果与其他答案一致。