1.问题
[描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)]
课本149页最近对问题
2.解析
[问题的理解和推导,可用电子版直接在此编写,也可用纸笔推导,拍照嵌入本文档]
当2<=n<=3,通过蛮力算法求解;当n>3,对所有的点按照坐标从小到大排序,利用点集在坐标方向的中位数m,在该处做一条垂线,将点集分为n/2和n/2两个子集P1和Pr,对左右两个部分分别求最近点对的距离d,然后进行合并。最近距离不一定存在于两个集合中,可能一个点在P1,一个点在Pr,而这两点间距离小于d。
3.设计
[核心伪代码]
EfficientClosestPair(P,Q){
if n<=3
返回蛮力算法求得的最小距离;
else
将P的前⌈n/2⌉个点复制到Pl;
将Q的前⌈n/2⌉个点复制到Q1;
将P中余下的⌊n/2⌋个点复制到Pr;
将Q中余下的⌊n/2⌋个点复制到Qr;
dl<—EfficientClosestPair(Pl,Q1);
dr<—EfficientClosestPair(Pr,Qr);
d<—min{d1,dr};
m<—P[⌈n/2⌉-1].x;
将Q中所有|x-m|<d的点复制到数组s[0…num-1];
dminsq<—d²;
for i=0 to num-2 do
k<—i+1
while k<=num-1 and (s[k].y-s[i].y)² < dminsq
dminsq<—min((s[k].x-s[i].x)²+(s[k].y-s[i].y)²,dminsq);
k<—k+1;
return sqrt(dminsq);
}
4.分析
[算法复杂度推导]
时间复杂度:O(n log n)
5.源码
[github源码地址]
https://github.com/RyokoJiang/homework/blob/main/Suanfa_5.cpp