问答题 5.  有20个数组,每个数组有500个元素,并且是有序排列好的,现在如何在这20*500个数中找出排名前500的数?
【正确答案】对于求top k的问题,最常用的方法为堆排序方法。对于本题而言,假设数组降序排列,可以采用如下方法:
   (1)首先建立大顶堆,堆的大小为数组的个数,即20,把每个数组最大的值(数组第一个值)存放到堆中。Python中heapq是小顶堆,通过对输入和输出的元素分别取相反数来实现大顶堆的功能。
   (2)接着删除堆顶元素,保存到另外一个大小为500的数组中,然后向大顶堆插入删除的元素所在数组的下一个元素。
   (3)重复第(1)、(2)个步骤,直到删除个数为最大的k个数,这里为500。
   为了在堆中取出一个数据后,能知道它是从哪个数组中取出的,从而可以从这个数组中取下一个值,可以设置一个数组,数组中带入每个元素在原数组中的位置。为了便于理解,把题目进行简化:三个数组,每个数组有5个元素且有序,找出排名前5的数。
   import heapq
   
   def getTop(data):
   rowSize=len(data)
   columnSize=len(data[0])
   result3=[None]*columnSize
   #保持一个最小堆,这个堆存放来自20个数组的最小数
   heap=[]
   i=0
   while i<rowSize:
   arr=(None,None,None)#数组设置三个变量, 分别为数值, 数值来源的数组, 数值在数组中的次序index
   arr=(-data[i][0],i,0)
   heapq.heappush(heap,arr)
   i+=1
   num=0
   while num<columnSize:
   #删除顶点元素
   d=heapq.heappop(heap)
   result3[num]=-d[0]
   num+=1
   if (num>=columnSize):
   break
   # 将value置为该数原数组里的下一个数
   arr=(--data[d[1]][d[2]+1],d[1],d[2]+1)
   heapq.heappush(heap,arr)
   return result3
   
   if __name__=="__main__":
   data=[[29,17,14,2,1],[19,17,16,15,6],[30,25,20,14,5]]
   print getTop(data)
   程序的运行结果为:
   30 29 25 20 19
   通过把ROWS改成20,COLS改成50,并构造相应的数组,就能实现题目的要求。对于升序排列的数组,实现方式类似,只不过是从数组的最后一个元素开始遍历。
【答案解析】

[考点] 如何找出排名前500的数。