【问题标题】:Designing a data structure that works in O(logn) time设计一个在 O(logn) 时间内工作的数据结构
【发布时间】:2012-02-21 20:48:49
【问题描述】:

我正在审核这个算法课的工作,我正在尝试做一些课堂上给出的练习题。这个问题让我很困惑,我无法解决这个问题。我的解决方案都没有在 O(logn) 时间内出现。谁能帮我解决这个问题??

问题: 假设我们有一个任意顺序的 n 个值 x1, x2, ... , xn 的序列,并且 寻求快速回答形式的重复查询:给定任意对 i 和 j 1 ≤ i

【问题讨论】:

  • 到目前为止你的想法是什么?
  • 提示:数据结构很可能是某种二叉树。
  • 巴特,我真的只是坐在课堂上。过去我听说它被称为审计,这就是我特别使用这个词的原因。
  • 很公平,但不管你的参与是什么:我敢肯定,如果你展示你迄今为止所做的事情(或解释你自己的想法),你会发现人们更愿意提供帮助。
  • “Audire”的意思是“倾听”,如果你碰巧在礼堂里,那你就是在审计。 :)

标签: algorithm data-structures big-o time-complexity


【解决方案1】:

对于 a1,a2,a3,...an 的输入,构造一个包含 (a1,..,ak) 最小值和 (ak+1,..,an) 最小值的节点,其中 k = n/ 2.

递归构造树的其余部分。

现在,如果你想找到 ai 和 aj 之间的最小值:

  1. 确定 i,j 的最低共同祖先。让它成为k
  2. 从 i 开始并继续移动,直到您点击 k。在每次迭代时检查子节点是否是左节点。如果是,则比较右子树的最小值并相应地更新当前最小值。
  3. 同样,对于j,检查它是否是正确的节点......
  4. 在节点 k 比较每个子树返回的值并返回最小值

【讨论】:

  • 任何不明白这个答案的人可以看我的,反之亦然。它们并不完全相同,但它们非常相似。我给出了图片而忽略了细节,而这给出了细节并忽略了图片。
  • @btilly,我认为这个答案所说的是一个段树。段树占用 O(nlogn) 空间,而不是 O(logn)。 en.wikipedia.org/wiki/Segment_tree
  • @Jack 有 2 种不同的数据结构被称为段树。这里描述的与 wcipeg.com 描述的相匹配,它使用 O(n) 空间。它可用于有效地找到任何区间内的最小值。维基百科描述的结构用于识别区间集合的哪个子集包含给定点的不同目的。这就是为什么我更关心事物的本质而不是它们的名称。因为不同的人称同一事物为不同的事物,而不同的事物称为同一事物。
【解决方案2】:

人们对此想得太多了。假设您从列表开始:

47, 13, 55, 29, 56, 9, 17, 48, 69, 15

制作以下列表:

47, 13, 55, 29, 56, 9, 17, 48, 69, 15
13,     29,     9,     17,     15
13,             9,             15
9,                             15
9

我将这些列表的构造、正确用法以及它们提供原始问题答案的证明留给读者作为练习。 (这对你来说可能不是家庭作业,但它很可能是给某人的,我不喜欢对家庭作业问题给出完整的答案。)

【讨论】:

  • 这是否使用O(n) 空间(根据需要)?
  • @ypercube 是的。看起来 ElKamina 选择提供我故意遗漏的所有细节,以便对这个解决方案进行细微的修改。
  • 啊,好吧,我想不出你是在提议这个。与列表或垂直列表相比,这更像是一个树结构,这并不明显。
  • @ypercube 是否将其视为树、列表、垂直列表,或者将其连接成单个数组是个人选择。它们都有效。
【解决方案3】:

我认为关键步骤是您需要事先对数据进行排序。然后您可以将数据存储在数组/列表中。然后您可以在 O(logn) 中快速进行二分搜索,找出满足条件的第一个值(我假设您的意思是在 xi 和 xj 之间,而不是 x1 和 xj)。

编辑:再三考虑,确保值满足条件可能不像我想象的那么简单

【讨论】:

  • 你会如何使用二分搜索?
  • 我认为教练的意思也是说 xi 和 xj 。我一个字一个字地抄了下来。那会更有意义,不是吗? :)
  • 如果数据已经排序,可以通过调整索引对其进行二分查找。 IE:设置一个left = 0,right =数组长度,mid = floor(左右平均)。然后如果 x
  • 如果数据已排序,您已经知道整体上最小的元素是列表中的第一个。所以你所能做的就是从第一个开始并迭代,直到找到索引在 i 和 j 之间的第一个元素。不过,这不是 O(logn)。
  • 问题在于它的顺序是任意的。那么还可以假设数据是排序好的吗?
【解决方案4】:

之前的提问方式略有不同:What data structure using O(n) storage with O(log n) query time should I use for Range Minimum Queries?

不过,为了快速回答,您面临的问题是一个经过充分研究的问题 - 范围最小查询。段树是一种数据结构,可以解决 O(N) 空间和 O(logN) 时间要求的问题。您可以在here 中查看更多详细信息,其中对结构和所涉及的复杂性进行了说明。

【讨论】:

  • 我认为段树有 O(nlogn) 空间
【解决方案5】:

尝试解释建议的数据结构:

对于每一对数字,计算并保留较小的数字的值。 对于每四个连续数字,计算并保留四个中最小的值。这可以通过选择两对值中较小的一个来快速完成。 对于每八个连续数字,计算并保留八个中最小的值。 等等。

假设我们想要 x19 到 x65 的最小值。

我们查看以下存储值: x32 到 x63 中最小的。 最小的 x24 到 x31。 最小的 x20 到 x23。 x19。 x64 到 x65 中最小的。

然后我们选择其中最小的一个。

【讨论】:

    猜你喜欢
    • 2018-03-27
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 2019-03-14
    • 1970-01-01
    • 2014-09-21
    相关资源
    最近更新 更多