【问题标题】:Range minimum query, dynamic array, interval tree, treap范围最小查询、动态数组、区间树、trap
【发布时间】:2018-01-03 22:43:48
【问题描述】:

我需要一种在 Python 中具有某种数据结构的算法,当每一步都给出两个新元素 e1、e2 时:

  • 查找第一个和第二个给定元素的插入位置(保持顺序)。
  • 在两个插入位置之间的区间内查找元素的最大值。
  • 在第二个给定元素的先前找到的插入位置插入,第二个给定元素与区间中找到的最大值加上一个常数配对。除非第二个给定元素已经存在,在这种情况下,我们只需要在新值更大时更新它的值。

这一步必须在不超过对数时间内完成,因为当这一步重复 N 次时,整个最坏情况的时间复杂度不会远离 O(NlogN)。

-- 例如: my_list = [(2,1), (4,3), (5,7), (9,1)]

如我们所见,元素 2 与其分配的值 1 配对,元素 4 与值 3 配对,5 与值 7 配对,9 与值 1 配对。而 my_list 是按第一个元素排序的对。

现在,给出两个元素,e1 = 3,e2 = 6。

(e1, ) == (3, ) 在 my_list 中的插入位置为索引 1,(6, ) 的插入位置为索引 3。

在 my_list 的索引 1 和 3 之间的元素中找到的最大值为 7,因为 (4,3)、(5,7) 的最大值为 7。

假设要添加的常数是 1,我们有:找到的最大值 + 常数 == 7 + 1 == 8。 我们有 e2 == 6,所以要插入的对是 (6, 8) 在索引 3 处。

在这一步的最后,my_list 必须是:[(2,1), (4,3), (5,7), (6,8), (9,1)]

-- 这个question linked here 非常相似,但与我对插入元素的索引的问题不同。在那个问题中,元素被添加到最后(附加),在我的情况下,插入必须以保留元素顺序的方式完成,以便可以在对数时间内找到下一个任意间隔的开始和结束.这就是为什么我认为,除了使用范围最小查询之外,我还需要使用一些高级数据结构,例如区间树或treap。

【问题讨论】:

  • 如果必须找到最大值的区间为空,则可以跳过该步骤。
  • 您是在寻找实施方案还是您的要求是什么,我不确定我是否理解您。 :)
  • @maytham-ɯɐɥʇʎɐɯ 我希望有人能给我一个提示。使用什么数据结构,是否肯定可以用范围最小查询来解决,等等
  • 您需要在线算法还是可以接受批处理?
  • @PetarPetrovic 每个步骤中任意给定的两个元素从整个过程的开始就不是已知的,如果这就是你的意思。虽然也许它们可以被预先计算。

标签: algorithm data-structures b-tree segment-tree rmq


【解决方案1】:

对于这种类型的工作,我通常使用增强的 B+ 树。请参阅此处了解 B+ 树是什么:https://en.wikipedia.org/wiki/B%2B_tree

从 B+ 树开始,我将扩充所有内部节点,以便与每个指向子节点的指针一起存储与以该子节点为根的子树中的所有键相关联的最大值。

这些额外的信息可以很容易地计算 O(log N) 中任何间隔的最大值,并且在您插入、删除和修改树中的项目时很容易维护,而不会改变 O(log N) 复杂度这些操作。

对于内存中的 B+ 树,每个节点最多 8 个左右的键通常是高效的。

【讨论】:

  • 感谢您的回答!我正在阅读 B 树和 B+ 树,然后我将尝试在 Python 中实现它。
  • Python 中是否有一段基本的代码或框架可以修改以满足我的需要?我发现的唯一一个是 GitHub 上的“纯 Python B 树和 B+ 树实现”,但代码超过 500 行,语法非常先进。
  • 我几乎从不使用 Python,但如果你指的是这个:gist.github.com/teepark/572734,那么它看起来差不多。摆脱 BTree 并保留 B+Tree。摆脱删除/缩小/合并的东西,因为你只需要添加。只剩下几百行了
猜你喜欢
  • 2017-01-16
  • 2016-03-02
  • 2021-08-17
  • 2015-10-02
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多