Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.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
Python 3SUM到特定值_Python_Algorithm_Subset Sum - Fatal编程技术网

Python 3SUM到特定值

Python 3SUM到特定值,python,algorithm,subset-sum,Python,Algorithm,Subset Sum,我目前有一个解决方案,但仍然有大约300%太慢。问题是从给定的列表中找到三个数的子集,其和为n goal = int(input().split()[1]) #The desired sum numbers = list(map(int, input().split())) #User-inputted numbers myDict = {} #Created so we can quickly check if a number is present in the list for i i

我目前有一个解决方案,但仍然有大约300%太慢。问题是从给定的列表中找到三个数的子集,其和为n

goal = int(input().split()[1]) #The desired sum
numbers = list(map(int, input().split())) #User-inputted numbers

myDict = {} #Created so we can quickly check if a number is present in the list

for i in numbers: #The amount of each number is stored in the dict, eg. 439797: 2
    if i in myDict:
        myDict[i] += 1
    else:
        myDict[i] = 1


numbers = sorted(numbers)


for start in range(0, len(numbers)):
    for end in range(1, len(numbers)):
        myDict[numbers[start]] -= 1 
        myDict[numbers[end]] -= 1 
        #This is done so that the same number isn't used twice
        if goal-numbers[start]-numbers[end] in myDict:
            if myDict[goal-numbers[start]-numbers[end]] > 0:
                print(goal-numbers[start]-numbers[end], numbers[start], numbers[end])
                quit()
        myDict[numbers[start]] += 1
        myDict[numbers[end]] += 1

您在内部循环中为字典编制了六次索引,这完全没有必要,并且可能占了您运行时间的大部分。您可以只使用一个索引操作,而无需对字典进行任何修改:

for i in range(0, len(numbers)):
    m = numbers[i]
    for j in range(i + 1, len(numbers)):
        n = numbers[j]
        if n != m:
            k = goal - m - n
            if k != m and k != n and k in myDict:
                # accept triple (m, n, k)
此外,正如评论中已经提到的,对输入进行排序没有意义

更新:同样从注释中,您的内部循环从1开始。这大约是你跑步时间的两倍

更新2:此外,鉴于不再需要字典中的计数,字典现在可以是一个集合(但不确定它是否会以任何有意义的方式影响性能)


更新3:添加了对
n!=我完全同意SHINBOI,但是如果你需要快速计算这些任务,C++是走的路。代码如下所示:

for (int i = 0, i < len(numbers); i++) {
    int m = numbers[i];
    for (int j = i + 1, j < len(numbers); j++) {
        int n = numbers[j];
        if (n != m) {
            int k = goal - m - n;
            if (k != m && k != n && myDict[k]) {
                doSomething();
        }
    }
}
for(int i=0,i
如果你要进行排序,你可以使用二进制搜索来加快第三个数字的搜索速度。请参阅@ChatterOne谢谢,但你的确切意思是什么?这比马上查字典快多少?我不太明白。你可以在这里找到同样的问题:关于这个主题的许多解决方案和讨论包括事实上,这不是完全相同的问题。你是对的-我可以找到很多现成的信息,但我想知道如何加快我的解决方案。数字是整数吗?n的范围是什么?有一个问题:如果输入中有两个相同的数呢?那么肯定是k=m或k=n吗?@Kurns:不,是
k!=m和k!=n
检查确保不会发生这种情况。不过,我忘了检查
n!=m
,我现在已经修复了它。