topN问题
topN问题:给出一个数组,找出前N个最大的元素。
topN问题可以用分治法解决,这个问题与快速排序类似,快速排序是用一个数对数组进行划分,topN问题则不需完成排序,只需划分出前n个最大的数字即可。所以可以采用快排中partition函数的操作,将每次操作的返回值与N作对比,若比N小则对N及其后续的元素继续进行划分,若比N大则对N及其之前的元素进行划分,直到找出N。
该方法的时间复杂度:Θ(n)
示例代码:
import random def partition(a,i,j): if i < j: key = random.randint(i,j) tmp = a[key] a[key] = a[j] a[j] = tmp k = i-1 for index in range(i,j): if a[index] > a[j]: k += 1 tmp = a[k] a[k] = a[index] a[index] = tmp else: k += 1 tmp = a[k] a[k] = a[j] a[j] = tmp #此处与快排不同,当欲划分的数组元素皆相同时会导致栈溢出,所以当元素相同时 #返回一个随机下标 if a[i] == a[j]: return random.randint(i,j) return k return i def find_top_n(a,i,j,top_index): top_ret = partition(a,i,j) #当返回值比top_index小时,对top_ret及后续元素继续进行划分 if top_ret < top_index: return find_top_n(a,top_ret,j,top_index) #当返回值比top_index大时,对top_ret及先前元素继续进行划分 elif top_ret > top_index: return find_top_n(a,i,top_ret,top_index) #当返回值等于top_index时,已找到TopN else: return top_ret def main(args): a = [] for i in range(10): a.append(random.randint(0,100)) print(a) find_top_n(a,0,len(a)-1,5) print(a) return 0 if __name__ == '__main__': import sys sys.exit(main(sys.argv))