【问题标题】:What is the most efficient way to find all pairs of numbers from a list of integers which add up to a separate given integer?从整数列表中找到所有数字对的最有效方法是什么,这些数字加起来是一个单独的给定整数?
【发布时间】:2021-02-09 09:51:47
【问题描述】:

我昨天接受了一次采访,并被要求提供一种方法来从列表中找到所有成对的数字,这些数字加起来是一个单独的整数,该整数与列表分开。该列表可以无限长,但例如:

numbers = [11,1,5,27,7,18,2,4,8]
sum = 9

pairs = [(1,8),(5,4),(7,2)]

我已经对列表进行排序并消除所有大于sum 数字的数字,然后执行两个嵌套的 for 循环来获取每个索引并遍历其他数字以检查它们是否总和为给定的数字,但被告知有一种更有效的方法......

我一直在尝试解决这个问题,但除了向后执行嵌套迭代之外什么都没有,但这似乎只是稍微更有效率。

有什么想法吗?

【问题讨论】:

    标签: math subset


    【解决方案1】:

    这可以在 O(n) 时间和 O(n) 辅助空间内完成;测试一个集合的成员需要 O(1) 时间。由于输出也占用了 O(n) 空间,辅助空间应该不是一个重要的问题。

    def pairs_sum(numbers, k):
        numbers_set = set(numbers)
        return [(x, y) for x in numbers if (y := k - x) in numbers_set and x < y]
    

    例子:

    >>> pairs_sum([11, 1, 5, 27, 7, 18, 2, 4, 8], 9)
    [(1, 8), (2, 7), (4, 5)]
    

    【讨论】:

    • 如果每次迭代程序都必须检查 y 是否在列表中,我不太明白 O(n) 是怎么回事?这肯定是一个 O(n^2) 操作吗?
    • 不检查 y 是否在列表中;它正在检查 y 是否在集合中。
    【解决方案2】:

    这是一种经典,但不确定 stackoverflow 是否适合提出此类问题。

    1. 按升序排列列表
    2. 两个迭代器,一个从列表末尾开始降序i1,一个从列表开头升序i2
    3. 循环
    while i1 > i2
        if (list[i1] + list[i2] == target)
            store {list[i1], list[i2]) in results pairs
            i1--
            i2++
        else if (list[i1] + list[i2] > target)
            i1--
        else if (list[i1] + list[i2] < target)
            i2++
    

    如果您避免使用平均在 O(n log n) 中可以通过快速排序完成的排序算法,则这应该在 O(n) 中,n 列表的长度

    注意:这个算法没有考虑输入列表有好几倍相同数字的情况

    【讨论】:

    • 排序不是 O(n) 时间。
    猜你喜欢
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    相关资源
    最近更新 更多