【问题标题】:Difference of elements of 2 sorted arrays within given interval给定区间内 2 个已排序数组的元素之差
【发布时间】:2016-10-18 16:57:22
【问题描述】:

假设我们有 2 个排序的整数数组 A 和 B 以及给定的区间 [L,M] 。如果 x 是 A 的元素并且 y 是 B 的元素,我们的任务是找到所有具有以下属性的 (x,y) 对:L

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

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

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

【问题讨论】:

  • 当您将 x、y、L 和 M 称为它们的索引或该索引处的值时,您能否在问题中澄清一下?一个小例子(每个数组中只有 5 或 6 个值)也会很有帮助。
  • 举个例子,假设 A ={ 1,2,3} , B={10,12,15} , L=12,M=14。我们想要 12

标签: arrays algorithm


【解决方案1】:

这里有一个解决方案。

在每个数组的开头有一个指针,例如数组 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) time 中可能的 (x,y) 对数

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

希望这会有所帮助。我让你来实施解决方案

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

Edit2:我在下面附上了我提出的方法的示例实现:

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

【讨论】:

  • 我可以问一个问题吗?这可能很简单,但我错过了一些东西。
  • "如果两者之间存在差异,则存储当前对,即 A[i] 和 B[j]"。存储该对后,下一步应该是什么?如果我选择增加 i 或 j ,恐怕我会失去一些对。
  • O(nlogn) 绝对比 O(n^2) 好得多。答案确实非常有用!谢谢!是否可能存在 O(n) 的算法?
【解决方案2】:

因为每个组合都有可能在指定范围内,最坏的情况是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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多