2010-12-14 74 views
1

我有兩個向量,每個包含n個未分類的元素,我怎樣才能在這兩個向量中獲得n個最大的元素?在兩個向量中選擇n個最大的元素

我的解決方案是將兩個向量合併成一個具有2n個元素的向量,然後使用std::nth_element算法,但是我發現效率不高,所以任何人都有更高效的解決方案。萬分感激。

+1

你想要n個元素還是單個第n個元素? – 2010-12-14 08:31:43

+1

與N相比,n是否接近N或是否非常小? – 2010-12-14 08:32:48

回答

1

您可以將元素推入priority_queue,然後彈出n元素。

+0

但是這具有N * log(N)複雜度。這個問題可以在O(N) – ltjax 2010-12-14 09:52:40

1

假設n遠小於N,這是非常有效的。獲得minElem很便宜,以L比如果n < < N.兩個向量的排序

L := SortedList() 
For Each element in any of the vectors do 
{ 
    minElem := smallest element in L 
    if(element >= minElem or if size of L < n) 
    { 
    add element to L 
    if(size of L > n) 
    { 
     remove smallest element from L 
    } 
    } 
} 
1
vector<T> heap; 
heap.reserve(n + 1); 

vector<T>::iterator left = leftVec.begin(), right = rightVec.begin(); 

for (int i = 0; i < n; i++) { 
    if (left != leftVec.end()) heap.push_back(*left++); 
    else if (right != rightVec.end()) heap.push_back(*right++); 
} 

if (left == leftVec.end() && right == rightVec.end()) return heap; 

make_heap(heap.begin(), heap.end(), greater<T>()); 

while (left != leftVec.end()) { 
    heap.push_back(*left++); 
    push_heap(heap.begin(), heap.end(), greater<T>()); 
    pop_heap(heap.begin(), heap.end(), greater<T>()); 
    heap.pop_back(); 
} 

/* ... repeat for right ... */ 

return heap; 

注意我用* _heap,而不是直接priority_queue因爲priority_queue並沒有其底層提供接入便宜插入排序數據結構。這是O(N log n),比原始O(N log N)方法稍好一些,如果n < < N

0

您可以在兩個矢量的概念上並行執行「n元素」算法很簡單(至少這個簡單的變體在平均情況下只是線性的)。

  1. 挑選一個關鍵點。
  2. 分區(標準::分區)通過該樞軸的兩個向量。你將有第一個向量由一些排序爲i的元素分割,第二個向量由排序爲j的某個元素分割。我在這裏假設降序。
  3. 如果i + j < n,則在右側爲n-i-j最大元素遞歸。如果i + j> n,則在左側遞歸n個最大的元素。如果你擊中i + j == n,則停止遞歸。

你基本上只需要確保在每一步中通過相同的樞軸分區兩個向量。給定一個不錯的支點選擇,這個算法在平均情況下是線性的(並且在原地工作)。

參見:http://en.wikipedia.org/wiki/Selection_algorithm#Partition-based_general_selection_algorithm

編輯:(希望)澄清的算法的位。

+0

中解決。如果你懶惰,你可以編寫一個簡單的迭代器包裝器,它「虛擬」連接你的數組,然後繼續使用std :: nth_element。但重新實現兩個數組的算法可能會更快。 – ltjax 2010-12-14 11:29:32

+0

你能提供更多的信息嗎?關於那個迭代器封裝。 – leo 2010-12-15 01:41:48

+0

您可以編寫一個類,它的行爲與向量的迭代器類似,並且對前n個索引的第一個向量中的元素和下n個索引中的第二個向量中的元素取消引用。 – ltjax 2010-12-15 10:03:28