按间隔排序统计

时间:2014-10-10 09:52:39

标签: algorithm

给定一组数字a[0], a[1], ..., a[n-1],我们得到了类似的查询:

输出k - a[i], a[i+1], ..., a[j]

范围内的最大数字

可以在每个查询的多对数时间(n)内回答这些查询吗?如果没有,是否可以平均结果并仍然获得良好的摊销复杂性?

编辑:这可以使用持久性细分树来解决 http://blog.anudeep2011.com/persistent-segment-trees-explained-with-spoj-problems/

2 个答案:

答案 0 :(得分:4)

是的,如果O(n log n)空间可用,可以在多字录时间内回答这些查询。

通过构造深度为log(n)的分段树来预处理给定的数组。因此,叶子节点与源数组相同,下一个深度节点包含已排序的2个元素子数组,下一个级别包含通过合并这些2个元素数组生成的4个元素数组,等等。换句话说,执行合并排序但是将每个合并步骤的结果保存在单独的数组中。这是一个例子:

root:   | 1   2   3   5   5   7   8   9 |
        | 1   2   5   8 | 3   5   7   9 |
        | 1   5 | 2   8 | 7   9 | 3   5 |
source: | 5 | 1 | 2 | 8 | 7 | 9 | 5 | 3 |

要回答查询,请将给定范围(最多2 * log(n)个子范围)拆分。例如,范围[0, 4]应该分为[0, 3][4],这会提供两个排序的数组[1 2 5 8][7]。现在问题被简化为在几个排序的数组中找到第k个元素。解决它的最简单方法是嵌套二进制搜索:首先使用二进制搜索从每个数组中选择一个候选元素,从最大的一个开始;然后在其他(较小的)数组中使用二进制搜索来确定此候选元素的等级。这允许在O(log(n)^4)时间内获得第k个元素。可能一些优化(如分数级联)或其他一些算法可以更快地做到这一点......

答案 1 :(得分:0)

有一个基于快速排序的名为QuickSelect的算法。它的平均情况是O(n)。当输入有序时,算法的最坏情况是O(n ** 2)。

它给出了确切的第k个最大数字。如果你想要范围,你可以编写一个包装器方法。