Arrays 在未排序数组中搜索的有效方法
我有一个未排序的数组,其中包含0到100范围内的值。我有多种格式查询(起始数组索引、结束数组索引、起始值、结束值)。我想返回其值位于startValue和endValue中的索引数组。朴素的方法是为每个查询花费O(n)时间,我需要高效的算法。另外,查询最初是未知的。在内存使用、预处理时间和查询时间方面有一些折衷。设h为可能值的范围(本例中为101)。理想情况下,您希望查询花费O(m)时间,其中m是返回的索引数。这里有一些方法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)。每个查询(开始、
- 构建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)
在内存使用、预处理时间和查询时间方面有一些折衷。设h为可能值的范围(本例中为101)。理想情况下,您希望查询花费O(m)时间,其中m是返回的索引数。这里有一些方法
- 构建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)
为什么要给出数据库和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)的查询,这将使您检查并返回每个元素。