【问题标题】:Range median query in an array in O(1) time using preprocessing使用预处理在 O(1) 时间内在数组中查询范围中位数
【发布时间】:2026-01-19 07:00:02
【问题描述】:

在课堂上,我们了解了 RMQ 到 LCA 到 RMQ 的问题以及如何支持 O(1) 时间内的操作范围最小查询。作为一项练习,我的教授分配给我支持操作:O(n) 空间中的范围中值查询、O(n) 预处理时间和 O(1) 选择时间。

假设我有一个包含 8、7、9、2、6、4、5、3 的数组 A。给定中位数(i,j),我们应该得到第 i 个和第 j 个元素(含)之间的中位数对数组进行排序。 A sorted 是 2, 3, 4, 5, 6, 7, 8, 9。例如 median(2,6) = A[4] = 6 (因为 4, 5, 6, 7, 8 的中位数是 6) .

我发现了其他建议使用段树的解决方案,但在这些情况下复杂度不是 O(1)。是否可以用我们解决 RMQ 到 LCA 到 RMQ 问题的类似方式来解决这个问题?

【问题讨论】:

  • 这里的中位数是什么意思? A[(i + j) / 2]?你如何解决偶数项目的中位数? (A[floor((i + j) / 2)] + A[ceil((i + j) / 2)]) / 2?
  • 我最近没有真正睡觉,数组是在我们计算中位数之前进行排序的。如果子数组的数量是偶数,那么正如你所说的那样。
  • 如果这个问题不包含排序,我之前的评论是O(1)
  • 我不能使用正常排序,因为排序的下限是 O(nlogn)。正如我所提到的,我需要使用需要 O(n) 时间的预处理方法。

标签: algorithm data-structures range time-complexity median


【解决方案1】:

这是无法通过比较实现的。如果是这样,您可以通过预处理输入并计算每个 i 从 0 到 N-1 的中值(i,i),在 O(N) 时间内比较对 N 个元素进行排序。

您可能误解了分配给您的任务 - 您可能应该计算 原始 数组的子数组的中位数,而不是数组的排序版本。

【讨论】:

  • 我认为他的意思是 median(i,j) 返回子数组 A[i,...,j] 的中位数,这是可能的,因为 median(i,i) 只会返回 A [i],我认为他的意思是范围最小查询(他正在谈论的相同 rmq)返回子数组中的最小值而不是排序数组中的最小值,因此范围中值查询应该是未排序子的中值数组。
  • @TomerWolberg:这会更有意义,这很可能是教授真正想要的,但与实际问题所说的不符。
【解决方案2】:

一种选择是使用非比较排序算法。我知道的示例是radix sortO(wn),其中w 是字长)和counting sortO(n+k),其中k 是最大键值)。这两者都与输入大小成线性关系。

然后,您可以在列表中查找正确的位置,即O(1) 操作。这两种排序方法都在您的空间要求之内——基数排序是O(n+k),计数排序是O(k)

【讨论】:

    最近更新 更多