问答题 5.  给定一个数组,找出数组中是否有两个数对(a,b)和(c,d),使得a+b=c+d,其中,a、b、c和d是不同的元素。如果有多个答案,打印任意一个即可。例如给定数组:[3,4,7,10,20,9,8],可以找到两个数对(3,8)和(4,7),使得3+8=4+7。
【正确答案】最简单的方法就是使用四重遍历,对所有可能的数对,判断是否满足题目要求,如果满足则打印出来,但是这种方法的时间复杂度为O(N4),很显然不满足要求。下面介绍另外一种方法——字典法,算法的主要思路为:以数对为单位进行遍历,在遍历过程中,把数对和数对的值存储在字典中(键为数对的和,值为数对),当遍历到一个键值对时,如果它的和在字典中已经存在,那么就找到了满足条件的键值对。下面使用字典为例给出实现代码:
   #用来存储数对
   class pair:
   def __init__(self,first,second):
   self.first=None
   self.second=None
   self.first=first
   self.second=second
   
   def findPairs(arr):
   #键为数对的和, 值为数对
   sumPair=dict()
   n=len(arr)
   #遍历数组中所有可能的数对
   i=0
   while i<n:
   j=i+1
   while j<n:
   #如果这个数对的和在map中没有, 则放入map中
   sums=arr[i]+arr[j]
   if sums notin sumPair:
   sumPair[sums]=pair(i,j)
   #map中已经存在与sum相同的数对了, 找出来并打印出来
   else:
   #找出已经遍历过的并存储在map中和为sum的数对
   p=sumPair[sums]
   print "("+str(arr[p.first])+","+str(arr[p.second])+"),("+\
   str(arr[i])+","+st(arr[j])+")"
   return True
   j+=1
   i+=1
   return False
   
   if __name__=="__main__":
   arr=[3, 4, 7, 10, 20, 9, 8]
   findPairs(arr)
   程序的运行结果为:
   (3,8),(4,7)
   算法性能分析:
   这种方法的时间复杂度为O(n2)。因为使用了双重循环,而字典的插入与查找操作实际的时间复杂度为O(1)。
【答案解析】

[考点] 如何从数组中找出满足a+b=c+d的两个数对。