2015-09-13 55 views
2

您能否提出一個有效的算法來從一組給定n個數字(未分類)中找到最小10個和最大10個數字?我想到的給定n個數字中的最小和最大10個數字

的一種方式將是對數組進行排序,然後從中挑選。

應該有更好的方法來做到這一點。

你能提出一種方法嗎?

這不是一個家庭作業問題。

+0

@Claudiu技術上我認爲只有局部排序算法可以通過OP使用。鏈接覆蓋它,但選擇只處理「第k」個最大數量,而不是「top-k」項目。雖然前者可以減少到後者,但我不確定是否可以採用其他方式來放棄複雜性。 – luk32

回答

3

Python標準庫有這個工作,已經進行(heapq.nlargest和heapq.smallest)。

對於你的情況,它會制定出製作最小堆和最大堆與數據集的第10名成員預填充,然後進行在數據單次,必要時更新堆:

FOR element IN remaining_data 
    IF element > top_of_min_heap 
    THEN update_min_heap(element) 
    ENDIF 

    IF element < top_of_max_heap 
    THEN update_max_heap(element) 
    ENDIF 
ENDFOR 

更新步取代現有的,最小的已經見過最大的最十最小的最十大,已經看到和。

這裏大致是Python標準庫中的代碼是什麼樣子:

def nlargest(n, iterable): 
    """Find the n largest elements in a dataset.                     

    Equivalent to: sorted(iterable, reverse=True)[:n]                   
    """ 
    if n < 0: 
     return [] 
    it = iter(iterable) 
    result = list(islice(it, n))  # pre-populate with the first n elements 
    if not result: 
     return result 
    heapify(result)     # arrange them into a minheap 
    for elem in it:     
     if element > result[0]:  # new elem is bigger than the smallest-of-the-large 
      heapreplace(result, elem) # replace top element with new element 
    result.sort()      # sort the top ten 
    return result      
0

你可能會想太多,你只需要一次掃描陣列和commparing的最大最小值和最大值最低它填補兩個陣列跟蹤10個最小值和10米的最大值。 O(n)

A sort has O(n log n)

2

是的。創建兩個大小爲kk=10)的堆,其中一個用less作爲比較器,另一個用more。兩個有兩個存儲「top k」元素的結構。

查看每個元素並放入每個堆中。如果要素走出去堆的,忘記他們,這意味着他們不是在排名前10位

我相信這是所謂的Hadian - 索貝爾算法的一些變化。這是堆排序的基礎。有點像分區(我相信霍爾算法)快速排序。這也可以用在這裏順便說一句。

這樣你O(n) * 2 O(log k)N元素次數heap_insert大小k。這是O(n log k),對於k=10基本上是線性的。

1

您可以使用快速選擇算法解釋here以找到一個整數排序的數組的第k最大數量。之後,您可以再次迭代陣列並檢查大於第k個最大元素的元素。所以在兩次迭代中,您可以找到前k個元素。同樣,您可以應用此方法來查找最小的k個元素。

選擇排名算法的時間複雜度是在平均情況下,其中n是陣列中的元素的數目爲O(n)。第二次遍歷數組也需要O(n)次。因此總的複雜性也將是O(n)。

該算法運行速度快於使用堆的方法。因爲使用這種方法時間複雜度將是O(nlogk)。

相關問題