【问题标题】:Create a database for init,insert,delete,median为 init、insert、delete、median 创建一个数据库
【发布时间】:2016-09-11 19:07:06
【问题描述】:

我需要创建一个在这种时间复杂度下工作的数据库:

  1. 初始化 O(1)

  2. 插入 O(logn)

  3. 删除 O(logn)

  4. 求中位数 O(1)

我正在努力寻找 O(1) 中的中位数。

我创建了一个空的 AVL 树,以及 1.、2.、3。像具有所需时间复杂度的魅力一样工作。我想过每次输入树时都持有一个指向中位数的指针,但是当我删除一个节点时,如何在树中找到 logn 中的中位数?因为我相信我做不到。这将需要大约 O(n) 的时间复杂度。这意味着 3. 在更新指针以找到新的中位数后将无法使用 O(logn) 复杂度。

有什么想法吗?

【问题讨论】:

  • 我认为每个节点都有子树大小的二叉树可以满足这个要求。
  • @GordonLinoff 所以每个节点都会有一个叫做'size'的字段,然后n/2值节点就是中位数?
  • 我相信一对平衡的二进制最小/最大堆,每个堆包含一半的集合,这样中位数是较大堆的顶部或两者的平均值,带有用于删除的反向指针,应该做这个把戏

标签: algorithm data-structures median avl-tree


【解决方案1】:

根据您已有的情况,有多种解决方案可以解决此问题:

  1. Order Statistics tree,它是二叉搜索树的一种变体,允许您通过其顺序统计快速(对数时间)访问元素。在您的情况下,您正在寻找 ceil(n/2)'th 元素。
    虽然这意味着您将在 O(logn) 中找到中值,但您可以在每次插入/删除后轻松缓存它,并且不会改变原始操作的复杂性 - 将保持 O(logn)

  2. 另一种(可能更简单)的方法是使用以下观察:
    在每次插入/删除非空集后,中位数可以执行以下三个选项之一:
    一个。保持相同的元素。示例:1,2,3 -> 1,2,3,4 - 中位数仍为 2,
    乙。向右移动一个元素。示例:1,2,3,4 -> 1,2,3,4,5 - 中位数从 2 更改为 3
    c。向左移动一个元素。示例:1,2,3,4,5 -> 1,2,3,4(与之前相同,相反)。

假设您可以在对数时间内找到“上一个”和“下一个”元素,只需很少的额外工作即可轻松维护指向中位数的指针。

【讨论】:

  • 我使用了最小和最大堆。
  • @IlanAizelmanWS 最小和最大堆不支持快速删除(无需更多工作来支持它)。此外,如果您发现其他更有用的东西,您不应该接受答案。如果您有不同的解决方案,可以回答您自己的问题(并接受它)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 2013-04-26
  • 2010-09-06
  • 2012-11-02
  • 2017-01-16
  • 2023-03-16
  • 2011-04-29
相关资源
最近更新 更多