鉴于3排序浮点阵列a[],b[]和c[],设计linearithmic算法找出三个整数i,j和k这样|a[i] - b[j]| + |b[j] - c[k]| + |c[k] - a[i]|是最小的。
a[]
b[]
c[]
i
j
k
|a[i] - b[j]| + |b[j] - c[k]| + |c[k] - a[i]|
我确实有一个解决方案,但是我认为这不是线性的。这就是我现在所拥有的:
assume minDiff = // some huge value for each entry in 'a' find an entry closest to it in 'b' and call it 'closestToA' find an entry closest to 'closestToA' in 'c' and call it 'closestToB' compute the diff: int currDiff = Math.abs(a[i] - closestToA) + Math.abs(closestToA - closestToB) + Math.abs(closestToB - a[i]); Replace minDiff with currDiff, if currDiff < minDiff
首先,我想知道是否有更好的解决方案?如果不是,那么我是否认为该解决方案没有线性运算的复杂性呢?可以使用二进制搜索找到最接近的数字。
问题来自“算法-第4版”。作者是Robert Sedgewick和Kevin Wayne,我正在准备下一次面试。
让我们看一下元素的一些潜在排序:
a[i] < b[j] < c[k]
然后我们可以看到以下主张成立:
Target = |a[i] - b[j]| + |b[j] - c[k]| + |c[k] - a[i]| = b[j] - a[i] + c[k] - b[j] + c[k] - a[i] = 2 * (c[k] - a[i])
因此,对于任何可能的排序,这都是使两个不同阵列中的两个元素之间的差异最小化。因此,只需对每个可能的组合(a和b,b和c,c和a)进行最小化即可,如您所参考的问题所示(可以在每对线性时间上完成)。
a
b
c
一旦找到对的最小化,从第三个数组中找到匹配的元素应该很容易-只需遍历该数组并检查每个元素即可。