1.问题
n个点在公共空间中,求出所有点对的欧几里得距离最小的点对。
2.解析
分析步骤如下:
①分解:
对所有的点按照x坐标从小到大排序(排序方法时间复杂度O(nlogn))。根据下标进行分割,使得点集分为两个集合。
②解决:
递归的寻找两个集合中的最近点对。
取两个集合最近点对中的最小值dis。
③合并:
最近距离不一定存在于两个集合中,可能一个点在集合A,一个点在集合B,而这两点间距离小于dis。其中合并的这一步具体展开:
我们假设从两部分分别求出的最近距离为 dis1 和 dis2 , dis = min( dis1, dis2 ),再假设分属两部分的情况下,A ( x1 , y1 ) 属于第一部分 ,B ( x2 , y2 )属于第二部分,且以 x 轴作为分割的量,我们可以断定,如果存在解 ,A 、B 两点一定处在中心分割线两侧 2*dis 长度之内的区间内,且经过相关证明,在这范围内的点不会超过6个。
3.核心代码
double getresult(int l, int r)
{
double end = max ;
int i = 0;
int j = 0;
int k = 0;
if (l == r)
return end;
if (r - l == 1)
return distance(l, r);
double distancel = getresult(l, (l + r) / 2);
double distancer = getresult((l + r) / 2+1, r);
end = min(distancel, distancer);
int t[1000] = { 0 };
for (i = l; i <= r; i++)
{
if (fabs(dis[(l + r) / 2].x - dis[i].x) <= end)
t[k++] = i;
}
for (i = 0; i <= k - 1; i++)
for (j = i + 1; j <= k - 1; j++)
if (dis[t[j]].y - dis[t[i]].y < end)
end = min(end, distance(t[i], t[j]));
return end;
}
4.时间复杂度
- T(N)=O(nlogn)