我有一个数据结构问题,我需要管理一个酒店,每个房间都有一个数字 $ 1-n $
它可以被占用。

可用数据结构: avl * 树,b树,阵列,堆栈,队列,二叉树。

$ o(n)$ 空格复杂性可用。

使用AVL或B树是必须的。

我必须支持这些功能:

1) $ \ text {init(n)} $ :用 $ n $ 空闲的房间,房间的索引是<跨越类=“数学集装箱”> $ 1-n $
这必须在 $ o(n)$ 时间复杂度

对于下一个功能: $ l $ $ r $ 不必是一个数字占用的房间 -

2) $ \ text {getunocc(l,r)} $ :gets $ l $ -left和 $ r $ - 右(不必是占用的房间号码),2个数字定义了一系列数字,我需要计算多少酒店房间不在它们之间占用(包括)。必须在 $ o(\ log_2 {n})上工作。$ 时间复杂度

3) $ \ text {getminunocc(l,r})$ :gets $ l $ -left和 $ r $ -right,2个数字,定义一系列数字,这个人在最小的房间里尚未占用的房间 $ lr $ (包括)。
必须在 $ o(\ log_2 {n})上工作。$ 时间复杂度

4) $ \ text {getout(r)} $ :它获得了一个房间号码并删除来自该房间/酒店的人,使房间号 $ r $ 未占用。
必须在 $ o(\ log_2 {n})上工作。$ 时间复杂度

我的go:

init:我考虑使用带有布尔数组的AVL树。
我们初始化它 $ o(n)$ ,只需制作一个假(未被占用),它需要 $ o(n) $

getunocc(l,r):我想到了这个公式:
$ \ text {#unocc}= r - l + 1 - \ text {占用} $ 所以我们需要查找在 $ lr $ 但我不确定如何在 $ o(\ log_2 {n})中这样做。$

getminunocc更难,因为我无法确定哪个值是最小的,假设 $ l= 3 $ $ r= 10 $ $ 3-8 $ 和房间 $ 10 $ 被占用,我需要返回 $ 9 $ (因为它是未占用的最小)

让我们说我有这个树(因为史蒂文建议建立一个未被占用的房间)所以在这个问题上,它是 $ \ text {init(10)} $ 现在我想做 $ \ text {getminunocc(5,7)} $ 所以它应该删除 $ 5 $ < / span>从树上占用。但在你建议的内容中,我们发现 $ l= 5 $ 的继承者,它是他的父级, $ 6 $ 并删除它,但是, $ 5 $ 未占用,我们希望返回最小,因此我们需要实际删除 $ 5 $ ,我错了吗?谢谢!

我会很感激你的帮助/提示来解决这个难题!谢谢!

有帮助吗?

解决方案

维护AVL树 $ T $ 包含未占用的房间的索引。对于树的每个顶点 $ v $ 树的数量,另外维护数字 $ \ eta(v)$ 的顶点在 $ t $ rooted at $ v $

1) init:使用键 $ \ {1,\ dots,n \} $ 创建AVL树。这需要 $ o(n)$ 时间。

2) getUnocc( $ l $ $ r $ ):找到与 $ l $ 中的 $ l $ 相关联的顶点 $ u $ 。 -Container“> $ t $ (可能 $ l $ 本身)。查找顶点 $ v $ $ r $ $ t $ (可能 $ r $ 本身)。如果 $ u $ 大于 $ v $ return $ 0 $ 。否则发现最不常见的祖先 $ w $ $ l $ $ r $ 。初始化 $ x $ 未占用的房间到 $ 0 $ 。 从 $ u $ (包含)到 $ w $ (独家)。每当您遇到顶点 $ z $ ,这样 $ z= U $ 或前一个顶点在散步是 $ z $ 的左子子,让 $ z'$ $ z $ (如果有)并添加 $ 1 + \ eta(z')$ to $ x $ (如果 $ z'$ 不存在然后添加 $ 1 $ to $ x $ )。 从 $ v $ (包含)到 $ w $ (独家)。每当您遇到顶点 $ z $ ,例如 $ z= v $ 或前面的顶点是 $ z $ 的正确小孩,让 $ z'$ $ z $ (如果有)并添加 $ 1 + \ eta(z')$ to $ x $ (如果 $ z'$ 不存在然后添加 $ 1 $ to $ x $ )。返回 $ 1 + x $

3) getMinunocc( $ l $ $ r $ ):搜索顶点 $ u $ $ l $ 中的 $ l $ 数学集装箱“> $ t $ (其中 $ l $ 可能是 $ l $ < / span>本身)。 如果 $ u $ 最多是大多数 $ r $ ,删除 $ u $ 从树减去 $ 1 $ 从值 $ \ eta(z)$ 所有适当的祖先 $ z $ $ u $ 。 否则<跨度类=“math-container”之间的所有房间都在> $ l $ $ r $ 已被占用。

4) getout(r):插入一个新的顶点 $ z $ ,带键 $ r $ 使用 $ \ eta(z)= 1 $ 。递增 $ 1 $ $ \ eta(z')$ 所有正确的祖先 $ z'$ $ z $

其他提示

这可以使用简单的数组完成。

请注意,复杂性取决于房间的总数,而不是占用房间的数量。所以我们也可以储存所有房间。 计数免费房间的诀窍与其他答案中的AVL树的情况基本相同。在Arraus的线性列表之上,我们构建一个完整的二叉树,使每个节点存储在下面的房间间隔内的空闲房间数量。

我们可以通过寻找房间 $ \ ell $ $ r $ 在树中,然后从两个路径发散的节点开始计数。然后for for for $ \ ell $ 我们将免费的房间计算到右侧,对于 $ r $ 免费房间向左。

从位置 $ \ ell $ 的下一下,如下所示。首先在树中取出直到我们找到一个我们从左侧出来的节点,右边的子树有一个不清楚的房间。然后去第一个免费点。

上下,左右使用位matic完成。我在奇怪的指数中铺设房间。上面的NDES甚至是。二进制索引中的尾随零的数量表示节点的级别。左节点以“01”结尾,然后零,右节点有“11”和零。

下图描绘了八个房间,存储在1,3,5位,...,13,15。 树中的数字表示免费房间。因此,在这种情况下,占用3,5,9,11,15被占用,表示房间2,3,5,6和8。

将完整的树存储为数组也是为二进制堆完成的。但是,表示不同。对于堆,根是阵列中的第一个节点。从这一个颠倒的东西。

许可以下: CC-BY-SA归因
不隶属于 cs.stackexchange
scroll top