Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查列表中的3个整数之和是否与另一个整数匹配?(python)_Python_Algorithm - Fatal编程技术网

如何检查列表中的3个整数之和是否与另一个整数匹配?(python)

如何检查列表中的3个整数之和是否与另一个整数匹配?(python),python,algorithm,Python,Algorithm,这是我的问题: 我有一个大整数(介于0到2^32-1之间的任何地方)。让我们打这个号码X。 我还有一个整数列表,目前未排序。它们都是唯一的数字,大于0小于X。假设此列表中有大量项目,比如说超过100000个项目 我需要在这个列表中找到最多3个加起来等于X的数字(我们称它们为A、B和C)。 A、 B和C都需要在列表中,并且它们可以重复(例如,如果X是4,我可以有A=1、B=1和C=2,即使1在列表中只出现一次) A、B和C可以有多个解决方案,但我只需要以最快的方式为每个解决方案找到一个可能的解决方

这是我的问题:

我有一个大整数(介于0到2^32-1之间的任何地方)。让我们打这个号码X。 我还有一个整数列表,目前未排序。它们都是唯一的数字,大于0小于X。假设此列表中有大量项目,比如说超过100000个项目

我需要在这个列表中找到最多3个加起来等于X的数字(我们称它们为A、B和C)。 A、 B和C都需要在列表中,并且它们可以重复(例如,如果X是4,我可以有A=1、B=1和C=2,即使1在列表中只出现一次)

A、B和C可以有多个解决方案,但我只需要以最快的方式为每个解决方案找到一个可能的解决方案

我尝试过创建如下的for循环结构:

For A in itemlist:
  For B in itemlist:
    For C in itemlist:
      if A + B + C == X:
        exit("Done")
但由于我的整数列表包含超过100000个项目,这会占用太多内存,而且会花费太长时间


有没有办法在不使用大量内存或不花费大量时间的情况下找到a、B和C的解决方案?提前感谢。

您可以使用类似的设置将运行时间从n^3减少到n^2

s = set(itemlist)
for A in itemlist:
    for B in itemlist:
        if X-(A+B) in s: 
            print A,B,X-(A+B)
            break

如果您想节省内存,还可以对列表进行排序并使用二进制搜索

借用@inspectorG4dget的代码,这有两个修改:

import itertools

nums = collections.Counter(itemlist)
target = t  # the target sum
for i in range(len(itemlist)):
    if itemlist[i] > target: continue
    for j in range(i+1, len(itemlist)):
        if itemlist[i]+itemlist[j] > target: continue
        if target - (itemlist[i]+itemlist[j]) in nums - collections.Counter([itemlist[i], itemlist[j]]):
            print("Found", itemlist[i], itemlist[j], target - (itemlist[i]+itemlist[j]))
  • 如果
    C
    ,那么我们可以使回路短路
  • 使用
    bisect\u left()
    而不是
    collections.Counter()
  • 这似乎运行得更快

    from random import randint
    from bisect import bisect_left
    
    X = randint(0, 2**32 - 1)
    itemset = set(randint(0,X) for _ in range(100000))
    itemlist = sorted(list(itemset))    # sort the list for binary search
    l = len(itemlist)
    
    for i,A in enumerate(itemlist):
        for j in range(i+1, l):         # use numbers above A
            B = itemlist[j]
            C = X - A - B               # calculate C
            if C <= B: continue    
            # see https://docs.python.org/2/library/bisect.html#searching-sorted-lists
            i = bisect_left(itemlist, C)
            if i != l and itemlist[i] == C:
                print("Found", A, B, C)
    
    来自随机导入randint
    从对分导入左对分
    X=randint(0,2**32-1)
    itemset=set(范围内(100000)的randint(0,X))
    itemlist=已排序(list(itemset))#对列表进行排序以进行二进制搜索
    l=len(项目列表)
    对于i,枚举中的A(项目列表):
    对于范围(i+1,l)内的j:#使用A以上的数字
    B=项目列表[j]
    C=X-A-B#计算C
    
    如果使用C,则可以在index1:结构并有3个变量
    index1、index2、index3
    ,并增加这些变量,而不是遍历列表。这样,您只需要为这些变量分配更多空间。您可以尝试首先对列表进行排序,如果
    A+B>X
    (在第二个
    for
    )或
    A+B+C>X
    (在第三个
    A+B+C>X中),则中断当前for嵌套循环。通过这样做,您可以节省一些计算,这就像一个反向算法。但是,我不确定它是否真的会表现得更好。注意:如果你的列表是[1,2,3],目标是9,那么你当前的循环会找到一个答案,说3+3+3是9,即使3只在你的列表中出现一次。因此,你应该考虑使用<代码>迭代器。组合作为@ CuthToGord4DGET推荐。@ RoBTBT虽然是可以接受的,但允许我重复列表中的项目,即使它们只出现一次。我不确定这是O(n ^ 2)。在doulble循环中测试集合包含的“in”语句不是常数时间。可能是O((n^2)logn)。set是使用哈希表实现的,该哈希表在运算符中提供O(1)查找时间。这里使用哈希表table@RobertB我认为
    set
    中的
    是O(1),因为由于散列值的存在,访问值被摊销。这就是为什么这个答案很聪明。做了一个实际测试。即使n=100000,
    语句中的
    也非常快,所以我错了。@RobertB:你没有完全错,只是最好的情况下的行为非常常见。您需要一组精心编制的具有相同哈希值的非相等值来获得O(N)性能。