这是一个面试问题。
给定一个整数数组和一个 stream 的间隔(整数对),找到落在流的每个间隔中的数组元素。你会使用什么阵列预处理?
答案 0 :(得分:9)
一种选择是通过将数组按升序排序来预处理数组。完成后,您可以通过对排序数组执行两次二进制搜索来找到属于间隔的所有元素 - 一个用于查找大于或等于间隔开始的第一个元素,另一个用于查找最后一个元素不大于间隔的端点 - 然后遍历数组以输出该范围内的所有元素。
如果使用标准排序算法(如quicksort或heapsort),则需要O(n log n)时间进行预处理,但如果使用基数排序,则可以在O(n log U)时间内完成(此处,U是最大的)范围内的整数)。然后查询每次花费时间O(log n + k),其中n是元素的数量,k是范围内元素的数量。
如果你想获得幻想,可以使用van Emde Boas tree(一种用于存储整数的专用数据结构)以指数方式加快速度。如果您使用的最大整数值是U,那么您可以在时间O(n log log U)中构建结构,然后在时间O(log log U)中进行端点范围搜索。然后,您可以在时间范围内找到所有元素O(log log U),给出一个O(k log log U)算法,用于查找范围内的所有匹配。
希望这有帮助!
答案 1 :(得分:3)
对数组进行排序,然后进行二进制搜索以查找数组中第一个元素的索引,该索引大于间隔开始,然后再次找到小于区间结束的第一个元素,并返回所有两者之间的整数。对于每个查找,它将是O(log N)
,其中N是整数的数量。
答案 2 :(得分:3)
答案取决于您的要求:
你有多少间隔说M?
当然,使用M * O(N logN)是过度的,特别是当M很大时,间隔也是如此。
另一种方法:使用O(N)额外空间。
prefix[i] = number of numbers in range 0 to i
可以在O(N)时间内完成。
现在,每个查询都需要O(1)时间:
query[l,r] = prefix[r] - prefix[l - 1] + 1
总时间复杂度为O(N logN + M)
答案 3 :(得分:1)
根据元素索引数组怎么样?
for (i in original_array) indexed_array[original_array[i]] = original_array[i]
for (j in stream) {
for (k=stream[j][0]; k<=stream[j][1]; k++)
if (indexed_array[k]) return indexed_array[k]
}
或者放置索引而不是整数:
for (i in original_array) indexed_array[original_array[i]] = i