Arrays 在未排序数组中搜索的有效方法

Arrays 在未排序数组中搜索的有效方法,arrays,database,sqlite,sorting,data-structures,Arrays,Database,Sqlite,Sorting,Data Structures,我有一个未排序的数组,其中包含0到100范围内的值。我有多种格式查询(起始数组索引、结束数组索引、起始值、结束值)。我想返回其值位于startValue和endValue中的索引数组。朴素的方法是为每个查询花费O(n)时间,我需要高效的算法。另外,查询最初是未知的。在内存使用、预处理时间和查询时间方面有一些折衷。设h为可能值的范围(本例中为101)。理想情况下,您希望查询花费O(m)时间,其中m是返回的索引数。这里有一些方法 。每个数组元素V[x]=y对应于一个二维点(x,y)。每个查询(开始、

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

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

  • 。每个数组元素V[x]=y对应于一个二维点(x,y)。每个查询(开始、结束、最小、最大)对应于这些边界之间的二维树中的范围查询。这个实现需要O(n)内存、O(n log n)预处理时间和O(sqrt n+m)时间(参见小节)。值得注意的是,这并不取决于h

  • 排序数组+最小堆(如果您自己使用,可以说是一个更容易的实现)

    • 构建h排序数组P0…h,其中Pk是值k出现在原始数组中的位置数组。这需要O(n)内存和O(n)预处理时间
    • 现在我们可以用O(logn)(使用二进制搜索)回答形式为next(pos,k)的查询:“从pos开始,k的下一个值出现在哪里?”
    • 要回答查询(开始、结束、最小值、最大值),首先收集next(开始、最小值)、next(开始、最小值+1)、…、next(开始、最大值)并用它们构建最小堆。这需要O(h logn)时间。然后,当堆的最小值在最末端时,将其从堆中移除,将其添加到要返回的索引列表中,并将其对应的P数组中的下一个元素添加到相应的位置。这样,每个查询的复杂度为O(h logn+m logh)
  • 我还有两个想法是基于范围最小的查询,但是它们分别需要O(nh)和O(nh log h)空间。查询时间提高到O(m)。如果这不是禁止性的,请让我知道,我会编辑答案来详细说明


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

  • 。每个数组元素V[x]=y对应于一个二维点(x,y)。每个查询(开始、结束、最小、最大)对应于这些边界之间的二维树中的范围查询。这个实现需要O(n)内存、O(n log n)预处理时间和O(sqrt n+m)时间(参见小节)。值得注意的是,这并不取决于h

  • 排序数组+最小堆(如果您自己使用,可以说是一个更容易的实现)

    • 构建h排序数组P0…h,其中Pk是值k出现在原始数组中的位置数组。这需要O(n)内存和O(n)预处理时间
    • 现在我们可以用O(logn)(使用二进制搜索)回答形式为next(pos,k)的查询:“从pos开始,k的下一个值出现在哪里?”
    • 要回答查询(开始、结束、最小值、最大值),首先收集next(开始、最小值)、next(开始、最小值+1)、…、next(开始、最大值)并用它们构建最小堆。这需要O(h logn)时间。然后,当堆的最小值在最末端时,将其从堆中移除,将其添加到要返回的索引列表中,并将其对应的P数组中的下一个元素添加到相应的位置。这样,每个查询的复杂度为O(h logn+m logh)
  • 我还有两个想法是基于范围最小的查询,但是它们分别需要O(nh)和O(nh log h)空间。查询时间提高到O(m)。如果这不是禁止性的,请让我知道,我会编辑答案来详细说明


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