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))