我最近在一次采访中遇到了这个问题但我失败了,现在正在寻找答案。
假设我有一大堆n个整数,所有不同的颜色。
如果订购了这个数组,我可以用x细分它 数组,所有大小y,除了最后一个,可能更少。 我可以提取第n个子数组并返回它,已经排序。
示例:数组4 2 5 1 6 3.如果y = 2且我想要第二个数组,则为3 4。
现在我所做的只是对数组进行排序并返回第n个子数组,该子数组采用O(n log n
)。但有人告诉我,在O(n + y log y)
中有一种方法可以做到这一点。我在互联网上搜索并没有找到任何东西。想法?
答案 0 :(得分:16)
您要查找的算法是Selection Algorithm,可让您在线性时间内找到k-th order statistics。该算法非常复杂,但标准C ++库可以方便地提供an implementation。
找到采访者想到的第k个排序区间的算法是这样的:
b=(k-1)*y
- O(N)e=k*y
- O(N)y
和b
之间会有e
个数字。将它们存储在一个大小为y
的单独数组中。此操作需要O(N)y
的数组进行排序。总成本为O(N + N + N + y * log 2 y),即O(N + y * log 2 y)
答案 1 :(得分:5)
您可以将std::nth_element
和std::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
之类的特殊情况,但这是一般性的想法。