给定一对整数对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)
更好的时间复杂性。
答案 0 :(得分:2)
让我们按非递增顺序按第二个值对我们的对进行排序。然后按此顺序迭代对。假设当前对具有索引i
,并查看所有对(j, i)
,其中j < i
。我们知道这些对中的第二个元素的最小值是pairs[i].second
(因为不增加的顺序)。然后我们需要找到索引的数量j
其中
|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)
。
如果对中的整数值为$(".checkedterms").change(function(){ //remove
//keep the code that's currently here
}); //remove
,则可以替换BST,例如Fenwick tree或Segment tree。
答案 1 :(得分:1)
当您将对子视为二维点时,您可以在坐标系中说明问题。
现在,您希望将每对(点)与点上方区域中的所有对(点)连接,该点具有该点的y坐标的宽度。下图给出了两个例子。以这种方式构建区域可确保:
现在的问题是,我们怎样才能快速找到该地区的分数。
对于这类查询,通常会使用R-Trees。您可以在O(n log n)中构建R树。查询复杂性取决于查询的选择性以及此问题对数据分布的影响。如果幸运的话,它是O(log n),但它也可能会收敛到每个点的O(n)。
但是,如果我理解你是对的,那么你对所有对都不感兴趣,而只是对数对。如果是这种情况,您可以在R-Tree页面中添加一个计数器,用于存储每页中存储的点数。那么你真的不需要验证所有可以使你更接近每点O(log n)的点。
答案 2 :(得分:0)
你的对是坐标。把他们当作职位。
对于给定的坐标(x,y),匹配的坐标形成从x轴终止的锥体,直到达到高度y。然后它变成一个宽度为2y + 1的列,以x为中心向上无穷大。
所以现在你需要一种方法来计算这样一个区域中的元素,而不需要做任何每个元素的工作。
想象一下,你有一个从(x,y)到该点上方和左边的点数的地图(称之为方形积累图)。然后计算列部分需要2次查找和减法。应该可以在O(n lg n)时间左右建立这样的地图。
类似的几何累积计数可用于有效地计算三角形或锥形区域中的元素计数。例如,如果我们有一个从k到#元素的映射(xy)&gt; = k,你可以计算一个三角形中元素的数量,在那里进行1次查找,3次查找到方形积累图,然后进行2次减法还有一个。
具有相反方向的对角线累积图,您现在可以计算锥形元素的数量,如上所述。
如果查找需要lg(n)时间,构建这些地图需要O(n lg n)时间,那么我们可以简单地迭代每个点(其中n个),计算附近点的数量(lg n work),总结一下,除以2(因为我们对每一个进行了重复计算),我们对你的问题有一个O(n lg n)解决方案。