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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM