更好的算法(比使用dict)枚举具有给定总和的对。

时间:2012-09-23 07:52:51

标签: python algorithm

给定一个数字,我必须找出给定数组中所有可能的索引对,其总和等于该数字。我目前正在使用以下算法:

def myfunc(array,num):
    dic = {}
    for x in xrange(len(array)):  # if 6 is the current key,
        if dic.has_key(num-array[x]):  #look at whether num-x is there in dic
            for y in dic[num-array[x]]: #if yes, print all key-pair values
                print (x,y),
        if dic.has_key(array[x]):  #check whether the current keyed value exists
            dic[array[x]].append(x)  #if so, append the index to the list of indexes for that keyed value
        else:
            dic[array[x]] = [x]  #else create a new array

这会在O(N)时间运行吗?如果没有,那么应该做些什么呢?在任何情况下,是否可以在O(N)时间内运行它而不使用任何辅助数据结构?

3 个答案:

答案 0 :(得分:6)

  

这会在O(N)时间内运行吗?

是和否。复杂性实际上是O(N + M),其中M输出大小
不幸的是,输出大小是O(N^2)最差的情况,例如数组[3,3,3,3,3,...,3]number == 6 - 它将导致需要生成二元数量的元素。

然而 - 渐渐地说 - 它不能比这更好,因为它在输入大小和输出大小上是线性的。

答案 1 :(得分:3)

非常非常简单的解决方案,通过使用数组引用实际上在O(N)时间内运行。如果你想枚举所有输出对,那么当然(如amit notes)在最坏的情况下必须采用O(N ^ 2)。

from collections import defaultdict
def findpairs(arr, target):
    flip = defaultdict(list)
    for i, j in enumerate(arr):
        flip[j].append(i)
    for i, j in enumerate(arr):
        if target-j in flip:
            yield i, flip[target-j]

后处理以获取所有输出值(并过滤掉(i,i)个答案):

def allpairs(arr, target):
    for i, js in findpairs(arr, target):
        for j in js:
            if i < j: yield (i, j)

答案 2 :(得分:1)

这可能有所帮助 - Optimal Algorithm needed for finding pairs divisible by a given integer k

(稍作修改,我们看到所有对都可以被给定的数字整除,而不一定只等于给定的数字)