一种从数字列表中查找一对和的算法?

时间:2010-02-20 01:52:16

标签: algorithm language-agnostic

假设您有以下数字列表{3,6,10,9,13,16,19},不一定按此顺序。现在,不知道这是集合{3,6,10}的可能组合的集合,是否存在可用于有效地找到这些组合的任何编程语言的算法。 基本上,我想从总集中恢复列表 - 其中包含所有数字。什么是有效的算法,如果已经存在,我不想重新发明轮子?

3 个答案:

答案 0 :(得分:5)

对于可以有任意数量元素的一般情况,这里是一个O(q * log(q))算法,其中q是输入列表的大小:

  1. 按升序对列表q进行排序。
  2. 删除最小元素m,并将其添加到结果集中。将其从q。
  3. 中删除
  4. 迭代q。保留我们见过的数字列表。如果我们看到一个数字(我们已经看过的数字+ m),那么丢弃它。这应该保留一半的数字(所有那些不涉及m)。
  5. 从步骤2开始重复,直到找到所有数字。
  6. 以下是Python中此算法的实现:

    def solve(q):
        q = sorted(q)
        x = []
        while q:
            x.append(q[0])
    
            s = [False]*len(q)
            s[0] = True
            j = 1
    
            for i in range(1, len(q)):
                if q[i] == q[0] + q[j]:
                    s[i] = True
                    j += 1
                    while j < len(q) and s[j]:
                        j += 1
    
            q = [k for k, v in zip(q, s) if not v]
        return x
    
    s = [1, 3, 7, 12, 13, 20, 25, 31, 32, 33, 62, 78, 80, 92, 99]
    from itertools import combinations
    q = list(sum(x) for r in range(1, len(s) + 1) for x in combinations(s, r))
    print(solve(q))
    

    结果:

    [1, 3, 7, 12, 13, 20, 25, 31, 32, 33, 62, 78, 80, 92, 99]
    

    原始答案:

    假设列表中只有3个数字,并且没有数字可以为负数:

    其中两个数字必须是列表中最小的两个数字。最大的数字必须是所有三个的总和。通过减法,您可以找到第三个数字。

答案 1 :(得分:4)

1)找到最小的两个数字,这些数字必须是原始列表的一部分。

2)找到它们的总和,列表中较小的一切必须是原始列表的一部分。

3)找到下一个最小的和并重复,直到完成两个数的所有总和。

每当您在原始列表中添加数字或查找总和时,请将其从大列表中删除。

4)继续使用3个数字总和,并继续增加,直到大列表为空。

修改

找到下一个最小的总和需要一个排序的数字列表。如果你的列表是A,B,C,D,E那么那么最小的和是A + B,下一个最小的和是A + C.

性能和它一样糟糕:2 ^ N,但是如果我正确地阅读你的问题,列表中包含你的原始列表和所有可能的总和,这将使你能够大大提高性能。

例如,你知道你要找多少个数字,这意味着你知道什么时候你只需要一个,并且因为你也知道列表中的最大数字,最后一个数字是最大数字减去所有数字添加到原始列表中。

答案 2 :(得分:0)

这是你如何做到的。或者至少是一个天真的解决方案。

首先,您按升序排序数字。假设A是有序结果列表,S是可以构造A的最小数字集。

循环通过A.虽然不存在S的一个子集,它加起来一个 i ,为S添加一个新数字,这样就可以了。

在第一次迭代中,这将添加min(A)。第二个数字可能会在S中。这是计算密集型的,因为对于你在A中检查的每个数字,你需要确保存在一个S的子集,它会添加到它并且你不添加数字这会创建一个S的子集,它会添加到A中的某些内容中。

你可以稍微优化一下,每当你向S添加一个数字时,你计算出所有可能的总和,包括那个新元素,然后从A中删除它们。继续进行直到你清空A。

如果数字可能是负数,则会变得复杂,但是你会看到这一点,因为为了实现这一点,必须有一个负面元素A.