【问题标题】:selection algorithm with partition带分区的选择算法
【发布时间】:2012-07-10 02:15:11
【问题描述】:

我们必须将整数一个接一个地输入到一个数组中。在输入过程进行的同时,我们可能会被要求从顶部(最大)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

我的方法是使用分区选择算法,但已经超过时间限制。

【问题讨论】:

  • 家庭作业?有什么问题?
  • 问题不成立。在第三次请求时,一个集合包含 7 个数字,因此不清楚它的第三部分是什么。七个订购的项目可以分成三个尽可能相等的部分,如 3+2+2 或 2+3+2 或 2+2+3,从而给出“前 1/3”21 11 921 11,得到答案911。任务描述确实定义了为什么它应该是 11 而不是 9。

标签: algorithm sorting


【解决方案1】:

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

另一种方法: 维护两个堆:一个最大堆H1 和一个最小堆H2

最大堆 (H1) 将保存 2/3 的最低数字,而最小堆将保留 1/3 最高的数字。

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


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

如果此解决方案为 O(nlogn + k) 的总复杂度 - 其中 n 是数字的数量,k 是“告诉数字”请求的总数。

注意:一个更简单的解决方案(虽然可能更慢)是保持列表排序(例如在 BSTskiplist 中),并使用二分查找来查找相关元素。

示例:

init:
H1 = {}
H2 = {}

input1:
H1 = {1}
H2 = {}

input7:
H1={1,7}
H2 = {}

input 9: //need to add a max, in this case: x > H2.max() -> add x to H2.
H1 = {1,7}
H2 = {9}

tell the number
H2.min() = 9

input 21: // 21>9 -> remove H2.min() add it to H1, add x to H2
H1 = {1,7,9}
H2 = {21}

input 8:
H1 = {1,7,8,9}
H2 = {21}

input 5: //remove max from H1, add max to H2, add x to H1
H1 = {1,7,5,8}
H2 = {9,21}

tell the number
H2.min() = 9

input 11: //remove min from H2, add it to H1, add x to H2.
H1 = {1,7,5,8,9}
H2 = {11,21}
tell the number
H2.min() = 11

【讨论】:

    【解决方案2】:

    (我认为这个问题是某种家庭作业(“我们必须”),因此我没有直接给出答案。)

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

    【讨论】:

    • 使用选择算法的缺点是它们在相对于输入的线性时间内运行。假设#requests 与#elements 是线性的,它将导致二次解,这比保持列表排序更糟糕。如果#requests 这当然不适用
    【解决方案3】:

    怎么样:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-12
      • 2016-07-06
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      相关资源
      最近更新 更多