【问题标题】:Amortized Time with Hash Table哈希表的摊销时间
【发布时间】:2021-04-03 11:53:34
【问题描述】:

我解决了问题的第一部分,但卡在了第二部分。

我有一部电梯,想支持以下内容:

Init()设置电梯从0层开始,运行方向为向上(该函数只调用一次,方向不能改变)。 O(1)

AddStop(K)在DS中保存电梯到达k层时应该停止。 O(log n) 而 n 是电梯的总停靠次数。

NextStop() 将电梯发送到下一个停止位置,如果它在最终可用的停止位置,则电梯将停留在当前位置。 O(1)。


我的解决方案:我使用 AVL 树,这样每个节点都有一个指针,指向恰好位于它之后的节点和它之前的节点(根据楼层号)

当我添加新楼层时,我相应地更改了它的 2 个指针,并将指针更改为树中受影响的节点。

第 2 部分:

已知在我调用AddStop(K)之后,电梯可以停在的最高楼层最大为2i。

新的复杂性时间要求:

Init() - O(1)。 (没变)

AddStop(K) - O(1)。用NextStop()摊销

NextStop() - O(1)。用AddStop(K)摊销

有人可以帮我解决第 2 部分吗?


更新:

我认为第 1 部分与解决第 2 部分无关,而且我非常相信我们应该在这里使用哈希表。

【问题讨论】:

    标签: algorithm data-structures time-complexity hashtable amortized-analysis


    【解决方案1】:

    重要的是这个条件:

    i 调用AddStop(K) 之后,电梯可以停在的最高楼层最大2i

    这意味着在最坏的情况下你会停在一半的楼层,所以有一个按楼层编号索引的数组并存储一个布尔值来表示是否停止并不是很浪费。

    对于NextStop(),只需从当前楼层位置进行迭代,直到找到下一层停止。

    为了保持摊销 O(1) 的复杂性,每当 AddStop 需要更大的数组时,将数组的大小调整为之前的两倍就足够了。这样,假设您最终有 X 个楼层,自上次调整大小以来将直接添加其中的 0 到一半,调整大小时必须复制一次一半到 1/4,从 1/4 到 1/8将被复制两次,1/8 到 1/16 被复制三次等 - 最差副本数为 1 + 2/2 + 3/4 + 4/8 + 5/16 等. - 这是 Nicole Oresme 的定理所说的极限总和 4 - 一个常数因子,所以仍然 O(1) 摊销。

    不涉及哈希表。

    【讨论】:

    • 谢谢,但是我有几个问题,比如我应该什么时候让我的数组更大,是当它满了一半以上还是最后一站越过数组的前半部分?
    • “这意味着最坏的情况是你停在一半的楼层”,这与给出的内容无关,因为我总是在最后一个索引超过一半时调整数组的大小
    • 如果您有一个包含 100 个条目的数组,那么您可以跟踪 1 到 100 层的停靠点。如果有人在 k > 100 的情况下调用 AddStop(k),那么您将数组扩大到至少 200 ,但可能高达 k * 2。这足以使摊销的 big-O 效率保持在 O(1)。
    • 再次:“这意味着最坏的情况是你停在一半的楼层”与给定的句子无关,这是真的,因为每次到达一半时我都会将数组大小加倍。 .. 另外,我要求使用 NextStop() 摊销的正式(使用会计方法或聚合分析)O(1),您甚至没有在计算中提到它,因为它可以使用 O(n)
    • @MrCalc 您没有在这个问题中要求进行正式分析(使用会计或汇总方法),但在使用您的 sock puppet 帐户的重复问题中:stackoverflow.com/questions/65485618/…
    猜你喜欢
    • 2018-02-13
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多