【问题标题】:Efficient way to search within unsorted array在未排序数组中搜索的有效方法
【发布时间】:2020-03-20 13:34:53
【问题描述】:

我有一个未排序的数组 A,其中包含 0 到 100 范围内的值。我有多个格式为 QUERY(起始数组索引、结束数组索引、startValue、endValue)的查询。我想返回其值位于 startValue 和 endValue 内的索引数组。天真的方法是为每个查询花费 O(n) 时间,我需要有效的算法。此外,查询最初是未知的。

【问题讨论】:

  • 为什么要给出标签databasesqlite?你在用吗?
  • 普通数组 A 无能为力,除非您愿意预处理 A 并将一些额外信息存储在其他数据结构中
  • 最坏的情况确实是 O(n)。但预期的复杂度是 O(range),其中range 是平均范围(即endIndex - startIndex + 1)。您是否允许预处理您的数组并创建一个单独的数据结构用于查询?但请注意,无论您做什么,最坏的情况仍然是 O(n):有人可能会提出一个类似 (0, n, 0, 100) 的查询,这会让您检查并返回每个元素。

标签: arrays database sqlite sorting data-structures


【解决方案1】:

在内存使用、预处理时间和查询时间方面存在一些权衡。让 h 成为可能值的范围(在您的情况下为 101)。理想情况下,您希望查询花费 O(m) 时间,其中 m 是返回的索引数。这里有一些方法。

  1. 2-d trees。每个数组元素 V[x] = y 对应一个二维点 (x, 是的)。每个查询(startendminmax)对应二维树中的一个范围查询在这些边界之间。此实现需要 O(n) 内存,O(n log n)每个查询的预处理时间和 O(sqrt n + m) 时间(参见complexity 部分)。值得注意的是,这不依赖于h

  2. 排序数组 + 最小堆(如果你自己动手,可以说是更容易实现)。

    • 构建 h 排序数组 P0...h 其中 P k 是值 k 在原始数组中出现的位置数组。这需要 O(n) 个内存和 O(n) 个预处理时间。
    • 现在我们可以在 O(log n)(使用二进制搜索)中回答 next(pos, k): "从位置pos开始,k的下一个值出现在哪里?"
    • 要回答查询(startendminmax),首先要收集 下一个(开始, min), 下一个(开始, min em> + 1), ..., next(start, max) 并用它们构建一个最小堆。这需要 O(h log n) 时间。然后,当堆的最小值至多 end 时,将其从堆中移除,将其添加到要返回的索引列表中,并在其位置添加对应的 中的下一个元素P 数组。这会产生每个查询 O(h log n + m log h) 的复杂度。
  3. 我还有两个基于linearithmic approach 的想法来确定最小查询范围,但它们需要 O(nh) 和 O em>(nh log h) 空间。查询时间改进为 O(m)。如果这不是令人望而却步,请告诉我,我将编辑答案以详细说明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    • 2019-02-27
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    相关资源
    最近更新 更多