第一个元素之间的差异小于或等于第二个元素的最小值的对的数量[关闭]
Posted
技术标签:
【中文标题】第一个元素之间的差异小于或等于第二个元素的最小值的对的数量[关闭]【英文标题】:Number of pairs of pairs with difference between first elements less than or equal to minimum of the second elements [closed] 【发布时间】:2018-01-29 15:43:05 【问题描述】:给定一个整数对数组pair<int,int>
,需要找到pair<>
的对数,使得对的第一个元素之间的绝对差小于或等于第二个元素的最小值对。
例如:
Pair 1: 2,5
Pair 2: 7,4
Since (7-2) <= min(5,4) it is a valid pair
PS:我期待比天真的 O(N*N)
更好的时间复杂度。
【问题讨论】:
老实说,乍一看,我看不到能够降低复杂性的调整,但我想肯定有一些基于对排序的小调整,但我看不出复杂性如何下降很多。 所以 - 作为输出,您期望与您的配对匹配的值的数组/向量 - 所以在您的示例中,您会得到一个[1, 0]
?
不,他想要元素的数量。根据问题,正确的输出是1
。想如果我找到比二次方更快的东西。如果我这样做,我会发布一个答案。
整数必须是非负数吗?
如果 5
【参考方案1】:
让我们按第二个值以非递增顺序对我们的配对进行排序。然后按此顺序遍历对。假设当前对具有索引i
,并查看所有对(j, i)
,其中j < i
。我们知道这些对的第二个元素的最小值是pairs[i].second
(因为非递增顺序)。然后我们需要找到索引的数量j
where
|pairs[j].first - pairs[i].first| <= pairs[i].second
让我们重新表述:我们需要找到位于区间内且索引为j < i
的对的第一个元素的数量:
[pairs[i].first - pairs[i].second, pairs[i].first + pairs[i].second]
这可以通过O(log(n))
中的augmented self-balancing BST(我们可以保留和更新每个顶点中的子节点数)来完成。
伪代码:
res = 0
sort pairs by second value in non-increasing order
for i = 1 to n
res += number of elements in BST on interval [pairs[i].first - pairs[i].second, pairs[i].first + pairs[i].second]
add pairs[i].first to BST
总体复杂度为O(n*log(n))
。
如果对中的整数值为O(n)
,则可以将BST 替换为Fenwick tree 或Segment tree。
【讨论】:
我不得不承认这是解决此问题的更好(可能是最佳)解决方案。【参考方案2】:当您将这些对视为二维点时,您可以在坐标系中说明问题。
现在您想将每一对(点)与位于该点上方区域中的所有对(点)连接,宽度为该点的 y 坐标。下图中给出了两个示例。以这种方式构建区域可确保:
-
您考虑的点的 y 坐标是上述所有点中的最小值。
点的x坐标之差不大于这个y坐标。
现在的问题变成了,我们怎样才能快速找到该区域内的点。
对于这类查询,通常使用R-Trees。您可以在 O(n log n) 中构建 R-Tree。查询的复杂性取决于查询的选择性以及在这个问题中的数据分布。如果幸运的话,它是 O(log n),但它也可能会收敛到每个点的 O(n)。
但是,如果我的理解是正确的,那么您并不是对所有配对感兴趣,而只对配对的数量感兴趣。如果是这种情况,您可以向 R-Tree 页面添加一个计数器,以存储每个页面中存储的点数。然后,您实际上不必验证所有可以使您更接近每点 O(log n) 的点。
【讨论】:
非常类似于我的工作;但是红点下方的 x 轴没有圆锥吗?如果红点是 (5,5),那么 (10, 5), (9,4), (8,3), (7,2), (6,1) 和 (5,0) 在一个火柴锥的边缘 确实非常相似。我想只向上匹配,这样你就可以避免重复。如果在红点下方的锥体中有一点,那么它会在自己的“连接步骤”中与红点连接,对吧? 是的。您仍然必须注意如何处理与您“水平”的事情。我想只数你左边的东西就可以避免那里的重复计算?而且你减少了你必须做的累积工作量,因为不再有对角线。【参考方案3】:你的配对是坐标。将它们视为职位。
对于给定的坐标 (x,y),匹配的坐标形成一个从 x 轴开始直到高度 y 的圆锥。然后它变成一个以 x 为中心的宽度为 2y+1 的列,一直到无穷大。
因此,现在您需要一种方法来计算此类区域中的元素,而无需对每个元素进行任何操作。
假设您有一张从 (x,y) 到该点上方和左侧 # 个点的地图(称为方形累积地图)。然后计算列部分需要 2 次查找和减法。应该可以在 O(n lg n) 时间左右建立这样的地图。
类似的几何累积计数可用于有效计算三角形或锥形区域中的元素计数。例如,如果我们有一个从 k 到 # of elements with (x-y)>=k 的映射,您可以在其中 1 次查找计算三角形中元素的计数,并在平方累加映射中查找 3 次,然后进行 2 次减法和1 个补充。
有一个相反方向的对角累积图,您现在可以按照上面的说明计算圆锥中的元素数。
如果查找需要 lg(n) 时间,构建这些地图需要 O(n lg n) 时间,那么我们可以简单地迭代每个点(其中 n 个),计算附近点的数量(lg n 工作),总结起来,除以 2(因为我们重复计算了每个),我们有一个 O(n lg n) 的解决方案来解决您的问题。
【讨论】:
以上是关于第一个元素之间的差异小于或等于第二个元素的最小值的对的数量[关闭]的主要内容,如果未能解决你的问题,请参考以下文章