选择两个向量中的n个最大元素

时间:2010-12-14 08:27:40

标签: c++

我有两个向量,每个向量包含n个未排序的元素,如何在这两个向量中获得n个最大的元素?

我的解决方案是将两个向量合并为一个带有2n个元素,然后使用std::nth_element算法,但我发现效率不高,所以任何人都有更有效的解决方案。真的很感激。

4 个答案:

答案 0 :(得分:1)

您可以将元素推送到priority_queue,然后弹出n元素。

答案 1 :(得分:1)

假设n远小于N,这非常有效。如果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
    }
  }
}

答案 2 :(得分: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),如果n <&lt;&lt;&lt;&lt;&lt;&lt; Ñ

答案 3 :(得分:0)

你可以非常简单地在两个向量上并行地进行“第n个元素”算法(至少是在一般情况下只是线性的简单变体)。

  1. 选择一个支点。
  2. 分区(std :: partition)该枢轴的两个向量。你将有第一个向量由一个排名为i的元素划分,第二个向量由一个排名为j的元素划分。我在这里假设降序。
  3. 如果i + j&lt; n,在右侧递归n-i-j个最大元素。如果i + j> n,在左侧递归n个最大元素。如果你点击i + j == n,请停止递归。
  4. 您基本上只需要确保在每个步骤中通过相同的数据透视分区两个向量。给定一个合适的枢轴选择,该算法在平均情况下是线性的(并且就地工作)。

    另请参阅:http://en.wikipedia.org/wiki/Selection_algorithm#Partition-based_general_selection_algorithm

    编辑:(希望)稍微澄清了算法。