我认为问题如下:
我们有一个大小为n的整数数组A,我们有测试用例t,在每个测试用例中,我们给出一个数字m和一个范围[s,e],即我们给出s和e,我们必须找到该数组范围内最接近的m数(A [s] -A [e])。
您可以假设索引的数组从1到n。
例如:
A = {5, 12, 9, 18, 19}
m = 13
s = 4 and e = 5
所以答案应该是18。
约束:
n<=10^5
t<=n
我能想到的只是针对每个测试用例的O(n)解决方案,我认为存在更好的解决方案。
答案 0 :(得分:9)
这是一幅草图: 从数据中创建segment tree。在每个节点上,除了左右索引等常用数据外,还可以存储以该节点为根的子树中找到的数字,以排序顺序存储。当您以自下而上的顺序构造分段树时,可以实现此目的。在叶子正上方的节点中,您按排序顺序存储两个叶子值。在中间节点中,您将数字保留在左子项和右子项中,您可以使用标准合并将它们合并在一起。树中有O(n)个节点,保留这些数据应该采用整体O(nlog(n))。
一旦有了这棵树,对于每个查询,沿着路径走,直到到达给定范围内的适当节点([s,e])。如教程所示,一个或多个不同的节点将组合在一起形成给定的范围。由于树深度为O(log(n)),即每个查询到达这些节点的时间。每个查询应为O(log(n))。对于完全位于范围内的所有节点,在存储在这些节点中的排序数组中使用二分搜索找到最接近的数字。再次,O(log(n))。找到所有这些中最接近的,这就是答案。因此,您可以在O(log(n))时间内回答每个查询。
我链接到的教程包含其他数据结构,例如稀疏表,它们更容易实现,并且每个查询应该给出O(sqrt(n))。但我对此并没有多想。
答案 1 :(得分:-1)
我很确定没有更快的解决方案。您的问题略有不同:
没有数组A,但每个测试用例都包含要排序的未排序数字数组。 (从s到e的A的数组切片。)
在这种情况下,显然没有比每个测试用例的线性搜索更好的方法。
现在,您的原始问题以何种方式比上述变化更具体?唯一添加的信息是所有切片都来自同一个数组。我不认为这个附加约束可以用于算法加速。
编辑:我有所纠正。段树数据结构应该可以工作。答案 2 :(得分:-1)
对数组进行排序并进行二进制搜索。复杂性:o(nlogn + logn * t)