这是该系列的第二篇。一维、三维的最邻近点对问题(Closest-Pair Problem):戳这里
PS:建议先快速浏览一维问题的分治解法。因为各维度的解决思路具有高度的关联性。
1 问题描述
现在二维下,点不再是线性分布了。对于两个二维点 p i = ( x i , y i ) p_i = (x_{i}, y_{i}) pi=(xi,yi)和 p j = ( x j , y j ) p_j = (x_{j}, y_{j}) pj=(xj,yj),它们之间的欧几里得距离为 ( x i − x j ) 2 + ( y i − y j ) 2 \sqrt{(x_i - x_j)^2 + (y_i - y_j)^2} (xi−xj)2+(yi−yj)2。
暴力算法只能枚举每个不同的点对。它的时间复杂度是 O ( n 2 ) O(n^2) O(n2)。
但是我们可以沿用一维的思维模式来解决这个问题。并且这时,由于排序也需要 O ( n l o g n ) O(nlogn) O(nlogn),按照分治思想可以把暴力法的复杂度降到 O ( n l o g n ) O(nlogn) O(nlogn)。
2 算法描述
2.1 开始前
首先对于一个乱序的点集 P P P,我们需要分别对 x x x和 y y y进行排序,得到 P x P_x Px和 P y P_y Py(注意是分别,而不是先后)。前者用于divide,后者用于merge。
2.2 Divide步骤
▲ 第一步:拆分
对于任意的点集 P P P,其中点的数量 ∣ P ∣ = n \vert P\vert = n ∣P∣=n,类似于一维情况,可以 P x P_x Px中第 ⌊ n / 2 ⌋ \lfloor n/2\rfloor ⌊n/2⌋个点的坐标(记为 x ∗ x^* x∗)处,将其分为 Q Q Q区与 R R R区。
准确来说,分区的标准是点在 P x P_x Px中的位置,小于等于 ⌊ n / 2 ⌋ \lfloor n/2\rfloor ⌊n/2⌋划入 Q Q Q区,反之 R R R区。不过按 x ∗ x^* x∗来理解会比较方便。
▲ 第二步: 维护有序数组
对于 Q Q Q区和 R R <

本文详细介绍了二维最邻近点对问题的分治解法,包括算法描述、关键步骤解析、伪代码及Java实现。通过对点集的划分与合并,结合鸽巢原理优化,实现了O(nlogn)时间复杂度的高效求解。
最低0.47元/天 解锁文章
1430

被折叠的 条评论
为什么被折叠?



