扩展 amit 的解决方案,而不是存储实际数字,您可以只存储间隔及其相关集。
例如使用 5 的间隔大小:
(1-5): [1,2,3,1000000]
(6-10): [2,1000000]
(11-15): [3]
(16-20): [1000000]
在 (1,7) 的情况下,您应该考虑区间 (1-5) 和 (5-10)(这可以通过知道区间的大小简单地确定)。与这些范围相交会得到 [2,1000000]。集合的二分搜索表明,确实,(1,7) 存在于两个集合中。
尽管您需要检查每个集合的最小值和最大值,以更好地了解间隔大小应该是多少。例如,如果最小值和最大值从 1 变为一百万,则 5 可能是一个糟糕的选择。
您可能应该保留它,以便可以使用二进制搜索来检查值,因此子集范围应该类似于 (min + max)/N,其中 2N 是需要二进制搜索的最大值数每组。例如,“集合 3 是否包含从 5 到 10 的任何值?” 这是通过找到最接近 5 (3) 和 10 (11) 的值来完成的,在这种情况下,不,它没有。您必须遍历每个集合并对可能在集合内的间隔值进行二进制搜索。这意味着确保当集合仅达到 10 时,您不会去搜索 100。
您也可以只存储范围(最小值和最大值)。但是,问题是我怀疑您的数字会被聚集在一起,因此没有太多用处。尽管如前所述,它可能对确定如何设置间隔很有用。
选择使用什么范围还是很麻烦的,太大了,构建数据结构需要很长时间(1000 *million * log(N))。太小了,你会开始遇到空间问题。范围的理想大小可能是这样的:它确保与每个范围相关的集合的数量大致相等,同时还确保范围的总数不会太高。
编辑:一个好处是您实际上不需要存储所有间隔,只需要存储您需要的间隔。虽然,如果您有太多未使用的间隔,明智的做法可能是增加间隔并拆分当前间隔以确保搜索速度快。如果游行时间不是主要问题,则尤其如此。