Python 查找满足A+;B=C+;D

Python 查找满足A+;B=C+;D,python,algorithm,python-2.7,Python,Algorithm,Python 2.7,使用Python2.7解决以下问题。发布我的代码,想知道是否还有其他聪明的想法可以让它运行得更快?我想可能会有一些想法先对列表进行排序,然后利用排序行为,但到目前为止还不清楚。我的代码是O(n^2)时间复杂度 问题 from collections import defaultdict sumIndex = defaultdict(list) def buildIndex(numbers): for i in range(len(numbers)): for j in

使用Python2.7解决以下问题。发布我的代码,想知道是否还有其他聪明的想法可以让它运行得更快?我想可能会有一些想法先对列表进行排序,然后利用排序行为,但到目前为止还不清楚。我的代码是
O(n^2)
时间复杂度

问题

from collections import defaultdict

sumIndex = defaultdict(list)

def buildIndex(numbers):
    for i in range(len(numbers)):
        for j in range(i+1,len(numbers)):
            sumIndex[numbers[i]+numbers[j]].append((i,j))

def checkResult():
    for k,v in sumIndex.items():
        if len(v) > 1:
            for i in v:
                print k, i

if __name__ == "__main__":
    buildIndex([1,2,3,4])
    checkResult()
给定一个整数数组A,找到满足A+B=C+D的值的索引,其中A、B、C&D是数组中的整数值。找出所有四足动物的组合

代码

from collections import defaultdict

sumIndex = defaultdict(list)

def buildIndex(numbers):
    for i in range(len(numbers)):
        for j in range(i+1,len(numbers)):
            sumIndex[numbers[i]+numbers[j]].append((i,j))

def checkResult():
    for k,v in sumIndex.items():
        if len(v) > 1:
            for i in v:
                print k, i

if __name__ == "__main__":
    buildIndex([1,2,3,4])
    checkResult()
输出,即总和值,以及总和可能产生该值的索引

5 (0,3)
5 (1,2)

考虑数组的所有元素都相等的情况。然后我们预先知道答案,但是仅仅打印结果将花费
O(n^2)
时间,因为有
n*(n-1)/2
个这样的对。因此,我认为可以肯定地说,对于这个问题,没有比
O(n^2)
更复杂的方法了。

考虑数组的所有元素都相等的情况。然后我们预先知道答案,但是仅仅打印结果将花费
O(n^2)
时间,因为有
n*(n-1)/2
个这样的对。因此,我认为可以肯定地说,对于这个问题,没有比O(n^2)更复杂的方法了。

是的,它可以用一种比O(n^2)更复杂的方法来完成。算法是:

  • 创建一个重复的数组假设indexArr[]存储原始数组元素的索引,比如Origar[]
  • 使用复杂度为O(nLogn)的算法按升序对origar[]进行排序。同样,在对Origar[]进行排序时,也会洗牌indexArr[]
  • 现在,您必须在排序数组中查找对,您将运行2个循环来查找所有可能的组合。假设您选择了
    origar[i]+origar[i+1]=sum。
  • 现在您将搜索iff
    sum origar[n]
    ,然后您将打破内循环和外循环,因为没有其他组合是可能的
  • 此外,如果
    sum>origar[j]
    没有其他组合可用于该和,则会中断内部循环

  • PS-最坏的情况是O(n^2)。

    是的,它可以以低于O(n^2)的复杂度的方式完成。算法是:

  • 创建一个重复的数组假设indexArr[]存储原始数组元素的索引,比如Origar[]
  • 使用复杂度为O(nLogn)的算法按升序对origar[]进行排序。同样,在对Origar[]进行排序时,也会洗牌indexArr[]
  • 现在,您必须在排序数组中查找对,您将运行2个循环来查找所有可能的组合。假设您选择了
    origar[i]+origar[i+1]=sum。
  • 现在您将搜索iff
    sum origar[n]
    ,然后您将打破内循环和外循环,因为没有其他组合是可能的
  • 此外,如果
    sum>origar[j]
    没有其他组合可用于该和,则会中断内部循环

  • PS-最坏的情况是O(n^2)。

    使用
    itertools的更快、更具Python风格的方法。组合:

    from collections import defaultdict
    from itertools import combinations
    
    def get_combos(l):
        d = defaultdict(list)
        for indices in combinations(range(len(l)),2):
            d[(l[indices[0]] + l[indices[1]])].append(indices)
        return {k:v for k,v in d.items() if len(v) > 1}
    

    计时结果


    定时码


    使用
    itertools的更快、更具Python风格的方法。组合:

    from collections import defaultdict
    from itertools import combinations
    
    def get_combos(l):
        d = defaultdict(list)
        for indices in combinations(range(len(l)),2):
            d[(l[indices[0]] + l[indices[1]])].append(indices)
        return {k:v for k,v in d.items() if len(v) > 1}
    

    计时结果


    定时码



    更适合codereview.stackexchange.com网站。您添加了错误的输出。实际输出:
    5(0,3)5(1,2)
    @GaneshMatkam,感谢您的更正。更新了。@AbhishekBansal,以前也试过类似的问题,他们说代码评审不是为了性能改进讨论,只是为了编码风格:(更适合codereview.stackexchange.com网站。您添加了错误的输出。实际输出:
    5(0,3)5(1,2)
    @GaneshMatkam,感谢您的更正。更新。@AbhishekBansal,以前也试过类似的问题,他们说代码审查不是为了性能改进讨论,只是为了编码风格。:(感谢sudomakeinstall2,投票支持你的回答。你认为有什么改进吗(即使仍然是O(n^2))如果我们进行排序,该怎么办?@LinMa如果您想查找具有指定总和的对,有一些方法可以从排序和二进制搜索中受益,但由于您想查找具有所有可能总和的所有对,我想不出对您现有代码的任何改进。谢谢sudomakeinstall2,您知道我的代码中有任何功能性错误吗?谢谢udomakeinstall2,投票赞成你的回答。你认为有什么改进吗(即使仍然是O(n^2))如果我们进行排序,该怎么办?@LinMa如果您想查找具有指定和的对,有一些方法可以从排序和二进制搜索中受益,但由于您想查找具有所有可能和的对,我想不出对您现有代码的任何改进。感谢sudomakeinstall2,您知道我的代码中有任何功能性错误吗?谢谢或者你的想法,然后投票支持你的回答,对于你的评论——“在排序数组中找到对,你将运行2个循环,找到所有可能的组合”,我想你的意思是在我的I和j循环代码中的相同实现?或者其他一些实现(例如,你从开始循环,另一个从结束循环)如果你能显示你的代码,那么你就可以很好的解释很多。对于你的评论“现在你将搜索IFF和是,它将作为你的实现,但是正如我所提到的,最坏的情况将和你的一样。我只是基于一些条件打破了我的循环。考虑排序的数组[7, 9, 11,14 ]。现在数组的最大值是14(n)。因此,如果你考虑7(i)+9(i + 1)=15(和),并且作为15>14,就不可能有组合。谢谢金正克,但是我不认为检查<代码>数字[i]+NUMANS[i+1 ] < /代码> max(数字)有帮助。例如,假设排序数组是[2,7,9,14],7(i)+9(i+1)=15(和)。