28、已知三个升序整数数组a[l], b[m]和c[n]。请在三个数组中各找一个元素,是的组成的三元组距离最小。三元组的距离定义是:假设a[i]、b[j]和c[k]是一个三元组,那么距离为:
Distance = max(|a[ I ] – b[ j ]|, |a[ I ] – c[ k ]|, |b[ j ] – c[ k ]|)
请设计一个求最小三元组距离的最优算法,并分析时间复杂度。
这道题的求解参见上篇博客第28题,这里讲一下我自己的关于这道题的思考。
(PS:这是第一篇原创的文章,写起来还是有点小激动,文中要是有疏漏和错误之处还请大家批评指针)
上午的时候看到这道题,觉得暴力求解是可以的,但是题目要求最优算法,所以我也不知道怎么写了,就看了一下上篇文章中关于这道题的分析思路,觉得似曾相识,这个怎么感觉和
排序数组中和为给定值的两个数字有点像,再继续顺着思路往下走,要是两个已排序(从小到大)的数组,a[n],b[m],如何求解两数组中差值(非负)最小的两个点,当然暴力求解肯定是可以的,有没有其他更好的算法呢?想想这个和排序数组中给定值的两个数字有没有什么关系?或者能不能从那个方法获取思路,对,方法大致是一样的,就是先分别取两个数组a[n],b[m]中最小的数a[i],b[j],计算两个数的差值,并记录下来currentMin,然后取min(a[i],b[j]),所在的数组,例如a[0]<b[0],就继续计算a[1]和b[0]的差值,并和currentMin比较,取较小者付给currentMin,直到其中一个数组已到最后一个数组元素了,停止。
代码如下:
int minDifference(int *arrayOne,size_t cntOne,int *arrayTwo,size_t cntTwo) { int i = 0,j = 0; int minDiff = abs(arrayOne[0]-arrayTwo[0]); int currentMin = 0; for (int k = 0; k != cntOne + cntTwo;++k) { currentMin = abs(arrayOne[i]-arrayTwo[j]); minDiff = ( currentMin > minDiff ) ? minDiff:currentMin; if (arrayOne[i] < arrayTwo[j]) if (++i >= cntOne) break; else if (arrayOne[i] > arrayTwo[j]) if (++j >= cntTwo) break; } return minDiff; }
这样想来,阿里的这道题其实是这个道题扩展到三个已排序数组的情况,这个三个题的解答思路大致是一样的,不过阿里这题更难,因为你要想到第一步:化简。