分区选择算法

时间:2012-07-09 11:54:40

标签: algorithm sorting

我们必须将整数输入到一个数组中。虽然输入过程正在进行,但我们可以要求查找数字中最小(最大)1/3的最小数字,任意次数

例如:

input 1

input 7 

input 9

tell the number

input 21

input 8

input 5

tell the number

input 11

tell the number
输出应该是:

9

9

11

说明:

  • 直到第一个查询,数组的数字为1 7 9,所以前1/3的数字为9.因为它们只是一个数字所以它也是最小的。
  • 当进行第二次查询时,数组看起来像1 7 9 21 8 5,所以排序数组将是:
    21 9 8 7 5 1,前1/3的数字将是21和9.最小的数字 将是9
  • 在最终查询数组中有1 7 9 21 8 5 11,在排序21 11 9 8 7 5 1时,前1/3的数字将是21和11.最小的数字是11。

数组中的整数总数可以是250000

我的方法是将选择算法应用于分区但超出时间限制。

3 个答案:

答案 0 :(得分:3)

为什么选择算法失败:
请注意,使用选择算法在#elements中是线性的。假设#equests在#elements中是线性的 - 它将导致二次解决方案,这就是超出时间限制的原因。

另一种方法: 保持两个堆:最大堆H1和最小堆H2

最大堆(H1)将保持2/3最低数字,而最小堆将获得1/3最高数字。

现在,对于您阅读的每个元素x,检查是否需要增加前1/3堆(H2),如果这样做:您需要添加max{x,H1.max()} 。如果您添加了H1.max() - 您需要将其从堆中删除,然后插入x。如果不需要添加,请检查x是否大于H2.min(),如果是,请删除最小格式H2,将其插入H1,然后添加{{1}转到x


注意:您在此解决方案中寻找的数字可以随时在H1中找到,它是最小堆(O(1))的最小值。

此解决方案为H2时的总体复杂性 - 其中O(nlogn + k)是数字,n是“告诉数字”请求的总数。

注意:一个更简单的解决方案(虽然可能更慢)将维护列表排序(例如BSTskiplist),并使用二进制搜索寻找相关元素。

示例:

k

答案 1 :(得分:0)

(我认为这个问题是某种功课(“我们必须”),因此我并没有直截了当地给出答案。)

重新制定任务:要求您使用在线算法找到第66个百分点。 There is already a SO question for the median,这是第50个百分点,所以你应该能够从那里适应。如果该算法不好,请对在线中值算法进行一些研究,其中大部分算法也适用于您的问题。

答案 2 :(得分:0)

怎么样:

  1. 以排序方式保留数组,插入成本= log(n)
  2. 从1/3 = O(1)
  3. 中获取最小值