让我们假设我们有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)不是最优的。是否有一个复杂度更高的算法?
答案 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)
时间
对于A=[1,2,3]
和B=[10,12,15]
以及L=12
和M=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