两个排序数组的最大对数

时间:2011-10-31 17:13:13

标签: java c++ c algorithm data-structures

这不是原始问题。我有一个复杂的问题,现在减少到以下几点:

有两个排序的数组AB分别带有mn个元素m = \Theta(n)o(mn)时间内运行的算法能否找到最大对数,使得A[i]-B[j] <= T其中T是常数?如何才能做到这一点?

编辑:

  1. 这些对应该是不相交的,即一个元素最多可以选择一次。

  2. 算法应该以little-o(mn)运行,这意味着在mn时间内运行的解决方案是不可接受的。

  3. 是否也可以找到我们选择的对?

  4. 澄清:

    如果数组是a_1, a_2, ..., a_mb_1, b_2, ..., b_n,我需要找到(a_i, b_j)对,|a_i - b_j| <= T。不允许多次选择元素。我们如何才能最大化给定阵列的对数?

3 个答案:

答案 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中的任何元素都不会被使用两次。