用于查找无序数组的第n个排序子数组的算法是什么?

时间:2015-11-27 12:30:09

标签: c++ algorithm

我最近在一次采访中遇到了这个问题但我失败了,现在正在寻找答案。

  1. 假设我有一大堆n个整数,所有不同的颜色。

  2. 如果订购了这个数组,我可以用x细分它 数组,所有大小y,除了最后一个,可能更少。 我可以提取第n个子数组并返回它,已经排序。

  3. 示例:数组4 2 5 1 6 3.如果y = 2且我想要第二个数组,则为3 4。

    现在我所做的只是对数组进行排序并返回第n个子数组,该子数组采用O(n log n)。但有人告诉我,在O(n + y log y)中有一种方法可以做到这一点。我在互联网上搜索并没有找到任何东西。想法?

2 个答案:

答案 0 :(得分:16)

您要查找的算法是Selection Algorithm,可让您在线性时间内找到k-th order statistics。该算法非常复杂,但标准C ++库可以方便地提供an implementation

找到采访者想到的第k个排序区间的算法是这样的:

  • 查找b=(k-1)*y - O(N)
  • 中的订单统计信息
  • 查找e=k*y - O(N)
  • 中的订单统计信息
  • yb之间会有e个数字。将它们存储在一个大小为y的单独数组中。此操作需要O(N)
  • 为O(y * log 2 y)成本对大小y的数组进行排序。

总成本为O(N + N + N + y * log 2 y),即O(N + y * log 2 y)

答案 1 :(得分:5)

您可以将std::nth_elementstd::sort合并为:

std::vector<int> vec = muchData();
// Fix those bound iterators as needed
auto lower = vec.begin() + k*y;
auto upper = lower + y;

// put right element at lower and partition vector by it
std::nth_element(vec.begin(), lower, vec.end());
// Same for upper, but don't mess up lower
std::nth_element(lower + 1, upper - 1, vec.end());
// Now sort the subarray
std::sort(lower, upper);

[lower, upper)现在是长度为y的第k个排序子阵列,平均具有所需的复杂度。

要在实际使用之前检查y = 1之类的特殊情况,但这是一般性的想法。