使用窗口大小和长输入运行中间带

Running Median with window size along with long input

本文关键字:运行 中间 输入 窗口大小      更新时间:2023-10-16

给定一个数据序列(可能有重复),一个固定大小的移动窗口,在每次迭代时从数据序列的开始移动窗口,这样(1) 从窗口中删除最旧的数据元素,并将新的数据元素推入窗口(2) 找到每次移动时窗口内数据的中值。

这里的窗户尺寸是7,我们称之为m。m=窗口大小n=按顺序排列的元素数量,可以是1000或10000

Median for 4, 6, 99, 10, 90, 12, 17,1,21,32  : 12
Median for 6, 99, 10, 90, 12, 17, 1,21,32  : 12
Median for 99, 10, 90, 12, 17, 1, 21,32 : 17
Median for 10, 90, 12, 17, 1, 21, 32 : 17

我每次都借助于m个元素的Quicksort(三个元素的中间值作为枢轴)来实现这一点。但这需要很多时间。每次都需要排序。我应该实现这里提到的最小和最大堆解决方案

最小-最大堆解决方案中的问题:

当一个新数据被推入窗口时,从其中一个堆中删除最旧的数据,并将新数据与最大和最小堆的顶部进行比较,以决定要放入哪个堆中的数据。然后,像第一次迭代一样找到中值。

  1. 如何从堆中找到删除最旧的数据,我们如何维护它。根据给定的例子,在第二时间4是最旧的元素,第三时间6是最老的元素。我们怎样才能把它从堆里移走。

  2. 继上述问题之后,如何在堆中找到数据元素是一个问题。堆是一个二进制树,而不是二进制搜索树。

如有任何帮助,我们将不胜感激。

编辑:我已经有输入数据了,所以没有插入。只发生在固定大小的队列或窗口中,而不是实际的输入序列。

感谢

除了堆DS之外,还保存一个指针(或引用)队列,其中队列中的每个元素都指向表示堆中相关条目的节点。

当您将窗口移动1:时

  1. 退出旧元素队列
  2. 跟随指针,在二进制堆中查找节点
  3. 用刚找到的节点"切换"最后一个"节点(最低级别中最右边的元素)
  4. 删除新的"最后"节点
  5. 重新堆积
  6. 使用下一个元素为二进制堆创建新条目
  7. 将节点刚刚添加的指针放入队列
  8. 重新计算中位数

对于正在运行的数据中值(插入和删除都发生在移动窗口中),使用单个二进制搜索树而不是移动窗口中元素的最小-最大堆可能更有用。

二进制搜索树也将是顺序统计树,存储在每个节点处扎根的子树的大小。

该树将能够在O(logn)中进行插入、删除和中值计算。

在上面给出的示例中,每个操作将具有时间复杂性O(日志7)。