【问题标题】:Data Structure for supporting certain operations in O(log n) time在 O(log n) 时间内支持某些操作的数据结构
【发布时间】:2021-03-04 08:38:03
【问题描述】:

考虑将 元组 (id, date, views) 存储在一些支持操作
insert(id, date, views) 的数据结构中 - 将元素插入数据结构和元素
如果已经存在,它只是更新视图。因此,每个 id 都将是唯一的,用于存储 dateview
只有视图会得到更新。
delete(id) - 删除对应 id 的元素
search(id) - 返回对应 id 对应的元组
findelementWithMaxView (日期) - 考虑所有具有第二部分的元组 (date)
大于或等于 dateparameter)返回查看次数最多的任何人。

我们可以制作什么样的数据结构,可以在 O(log(n)) 时间内支持所有这些操作

我的想法:
我们可以简单地用 postId 作为键创建一个 AVL 树。这将支持插入、删除和搜索
在 O(log n) 中。但是仅仅做这个对 O(log n) 中的 findelementWithMaxView(date) 函数没有帮助

如果我用 date 键创建另一棵 AVL 树,并且树的每个节点都存储一个额外的信息
那是 (max-views, id) 其中 ma​​x-view 是具有该节点的子树的最大视图
id 是具有最大视图的元组的 id。
不确定这是否会完成 O(log n) 中的所有操作

【问题讨论】:

    标签: algorithm avl-tree


    【解决方案1】:

    你的思路是正确的 - 有一个警告

    你的思路是对的。拥有两个在每一步都修改的 O(log(n)) 数据结构将导致 O(log(n) + log(n)) 的复杂度仍然是 O(log(n))。

    • Insert(id): 将(id、日期、视图)插入到第一个结构中,以 id 作为键 - log(n)。在第二个结构中找到日期键并替换 id,如果需要查看 - log(n)。所以插入就OK了。
    • 搜索(id):日志(n),不需要其他任何东西 - 好的。
    • Update(id): log(n) 进行搜索,然后更新视图。这意味着我们将需要在二级结构中执行搜索,以在必要时更新 max-views 和 id。由于我们可能只会增加观看次数,因此我会给您一点余地,说这是 log(n)。
    • FindElementWithMaxDate(date) 由于二级结构,这将在 log(n) 内进行管理。

    现在这里有一个没有涉及的有趣问题:日期是唯一的吗?如果是,那么一切都很好,删除作品,我们都可以去唱 kumbaya。
    但是我有点相信事实并非如此 - 如果日期是唯一的,则没有必要有单独的日期和 ID。 (虽然它可能仍然有用,但可能是一个好习惯?)经过一番思考,我得出一个结论,两种情况都是可能的。那么如果日期不是唯一的会发生什么?

    如果日期不是唯一的,则删除/减少中断。
    由于我们只将 (max-views, id) 存储在我们的二级结构中,我们遇到了麻烦。 max-views 的删除给我们留下了不可能的任务,即在没有任何准备的情况下找到 2nd-max。因此,我们必须通过 date 遍历所有元素 - 最多可以有 O(n) 个元素。1

    那么可以做些什么呢?
    由于 ID 是唯一的,因此将 ID 用作决胜局。所以我们有一个 AVL 树,其中 date 作为 key,id 作为 tiebreaker。此外,树的每个节点都需要保存 maximum_views(node, left_subtree, right_subtree) 以便我们可以快速回答日期间隔1的问题。


    1 平均会有 O(sqrt(n)) 个。这并没有那么糟糕,但它比我们想要的 O(log(n)) 更糟糕。
    2 在我们的例子中是 [date: last_date]。

    【讨论】:

    • 是的,日期不必是唯一的。所以我的理解是,您将日期的所有元组存储在辅助 AVL 树的单个节点中。并将它们存储在堆中,键为views。但是函数 findelementWithMaxView >=certain-date 在 O(log n) 时间内仍然无法工作。因此,除了堆之外,我们还需要将子树的 (max-views,id) 存储在节点内。纠正我。这有点令人困惑......
    • 啊,是的。它变得混乱,所以我忘记了那一部分。将最大(子树)存储在每个堆的根中是必要的。然后,当您以更改最大值的方式更新任何堆时,您需要将新的最大值向上冒泡到根。让我编辑答案。
    • 如果日期不是唯一的,那么您可以使用 ID 来打破平局。
    • 确实如此。我可能过于复杂了^^。
    • 哦,是的,我认为这很重要。因此,只需使用 (date,id) 作为辅助 AVL 树中的键,因此在 O(log n) 中一切皆有可能。我们仍然会在每个节点中存储额外的信息 {max-view, id}。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    相关资源
    最近更新 更多