给定间隔内2个排序数组的元素差异

时间:2016-10-18 16:57:22

标签: arrays algorithm

让我们假设我们有2个排序的整数数组A和B以及给定的区间[L,M]。如果x是A的元素而y是B的元素,我们的任务是找到具有以下属性的所有(x,y)对:L< = y-x< = M. 哪个是最适合此目的的算法?

到目前为止,我已经考虑过以下解决方案: 蛮力。使用双循环检查所有可能元素对的差异.Complexity O(n ^ 2)。

上一个解决方案稍微不同的一个版本是利用这样一个事实:一旦差异超出间隔,数组就会通过不检查A的元素进行排序。复杂性仍然是O(n ^ 2)但希望我们的程序在平均情况下运行得更快。

但是,我认为O(n ^ 2)不是最优的。是否有一个复杂度更高的算法?

2 个答案:

答案 0 :(得分:3)

这是一个解决方案。

在每个数组的开头有一个指针,表示数组A为i,数组B为j

计算B [j]和A [i]之间的差异。

如果小于L,则增加数组B []中的指针,即将j增加1

如果它超过M,则递增i,即A的指针。

如果差异介于两者之间,请执行以下操作:

  • 搜索值为B[j]-A[i]-L或最近的元素的位置 元素,其值小于数组A中的(B[j]-A[i])-L 花费O(logN)时间。说位置是p。增加计数 (x,y)由p-i+1

  • 配对
  • 仅递增指针j

我的解决方案仅计算O(NlogN)时间

中可能的(x,y)对的数量

对于A=[1,2,3]B=[10,12,15]以及L=12M=14,答案为3

希望这会有所帮助。我留给你,实施解决方案

编辑:枚举所有可能的(x,y)对将花费O(N^2)最差情况时间。我们将能够在O(NlogN)时间内返回此类对(x,y)的 count 。很抱歉没有提前澄清。

编辑2:我在下面附上我提议的方法的示例实现:

def binsearch(a, x):

    low = 0
    high = len(a)-1
    while(low<=high):
        mid = (low+high)/2
        if a[mid] == x:
            return mid
        elif a[mid]<x:
            k = mid
            low = low + mid
        else:
            high = high - mid

    return k

a = [1, 2, 3]
b = [10, 12, 15, 16]
i = 0
j = 0

lenA = len(a)
lenB = len(b)

L = 12
M = 14
count = 0 
result = []
while i<lenA and j<lenB:
    if b[j] - a[i] < L:
        j = j + 1
    elif b[j] - a[i] > M:
        i = i + 1
    else:
        p = binsearch(a,b[j]-L)
        count = count + p - i + 1
        j = j + 1

print "number of (x,y) pairs: ", count

答案 1 :(得分:0)

因为每个组合都可能在指定的范围内,最坏的情况是O([A] [B]),基本上是O(n ^ 2)

但是,如果你想要最简单的算法,这就是我想出来的。它类似于user-targaryen的算法,但以简单的方式处理重叠

Create three variables: x,y,Z and s (set all to 0)
Create a boolean 'success' and set to false
Calculate Z = B[y] - A[x]
if Z < L
    increment y
if Z >= L and <= M
    if success is false
        set s = y
        set success = true
    increment y
    store x,y
if Z > M
    set y = s   //this may seem inefficient with my current example
                //but you'll see the necessity if you have a sorted list with duplicate values)
                //you can just change the A from my example to {1,1,2,2,3} to see what I mean
    set success = false

一个例子: A = {1,2,3,4,5} B = {3,4,5,6,7} L = 2,M = 3

在此示例中,第一对是x,y。第二个数字是s。第三对是值A [x]和B [y]。第四个数字是Z,A [x]和B [y]之间的差值。最终值为X表示不匹配,O表示匹配

0,0 - 0 - 1,3 = 2 O
    increment y
0,1 - 0 - 1,4 = 3 O
    increment y
0,2 - 0 - 1,5 = 4 X
    //this is the tricky part. Look closely at the changes this makes
    set y to s
    increment x
1,0 - 0 - 2,3 = 1 X
    increment y
1,1 - 0 - 2,4 = 2 O
    set s = y, set success = true
    increment y
1,2 - 1 - 2,5 = 3 O
    increment y
1,3 - 1 - 2,6 = 4 X
    set y to s
    increment x
2,1 - 1 - 3,4 = 1 X
    increment y
2,2 - 1 - 3,5 = 2 O
    set s = y, set success = true
    increment y
2,3 - 2 - 3,6 = 3 O
... and so on