这不是原始问题。我有一个复杂的问题,现在减少到以下几点:
有两个排序的数组A
和B
分别带有m
和n
个元素m = \Theta(n)
在o(mn)
时间内运行的算法能否找到最大对数,使得A[i]-B[j] <= T
其中T是常数?如何才能做到这一点?
编辑:
这些对应该是不相交的,即一个元素最多可以选择一次。
算法应该以little-o(mn)运行,这意味着在mn时间内运行的解决方案是不可接受的。
是否也可以找到我们选择的对?
澄清:
如果数组是a_1, a_2, ..., a_m
和b_1, b_2, ..., b_n
,我需要找到(a_i, b_j)
对,|a_i - b_j| <= T
。不允许多次选择元素。我们如何才能最大化给定阵列的对数?
答案 0 :(得分:3)
在O(n lg n) = O(m lg m)
中:从A
的元素创建平衡二叉搜索树,并在每个节点中存储元素的索引以及元素值。对于B
的每个元素,搜索小于或等于B[j] + T
的最大值。此数字的索引将告诉您有多少数字小于或等于此数字。
答案 1 :(得分:3)
更新2:
更新后的问题(仅使用一个数组中的元素,获取对,并且值的绝对差值必须低于T
)可能可以在 O(n +)中完成m)时间。我没有想过通过下面的算法足以决定它是否总是得到最大数量的对,但它应该在大多数情况下:
int i = 0;
int j = 0;
while(i < A.length){
while(j < B.length){
if(A[i]-B[j] <= T){
if(A[i]-B[j] >= -1 * T){
addPair(i, j);
j++;//don't consider this value the next time
}
break;
}
j++;
}
i++;
}
答案 2 :(得分:0)
如果您想要匹配|A[i]-B[j]| <= T
的对数,则每个A[i]
和B[j]
只在所有对中使用一次:
int lastB = 0;
int result=0;
for(int a = 0; a<A.size(); ++a) {
const int minB = A[a] - T;
while(lastB<B.size() && B[lastB] < minB)
++lastB;
const int maxB = A[a] + T;
if (lastB<B.size() && B[lastB] > minB) {
++lastB;
++result;
}
}
return result;
此算法扫描B
中的最小范围,并确保B
中的任何元素都不会被使用两次。