将所有点之间的距离遍历一遍。n 个点就需要遍历 $C_n^2$ 次。
时间复杂度:
空间复杂度:
暴力法显然时间复杂度过高,数据量较大的时候就不适合了。所以我们使用分治法进行优化。
首先简单介绍一下分治法:
分治法字面上的解释是“分而治之”,就是将复杂的问题分解成多个简单的问题进行求解。
分治法适用的场景:
该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
分治法的基本步骤:
分解原问题为结构相同的子问题。
分解到某个容易求解的边界之后,进行递归求解。
首先我们知道,一个点和两个点的时候求解很简单,那么我们能不能想办法将原问题分解为一个点或者两个点的情况。
那么我们将原始的点对分解成两部分,那么最近的点对就有三种情况:全在左边,全在右边,两边各一个 。所以最终解就是三种情况中的最小值。
下面着重讨论两边各一个点的情况。最简单的方法就是使用蛮力法,直接将左边所有的点挨个和右边的点算距离,然后找出最小值。但这样的话总体看起来和暴力法差不多了,所以我们需要进一步优化:
接着按照点的 y 值排序。此时对于左边的点来说,只要判断右边与该点 y 值最近的六个的点即可。这个结论可以用反证法或鸽舍原理进行证明:
反证法证明:
分治过程:
对于每个左边的点,都要和 6 个右边的点进行比较,故时间复杂度计算公式为:
带入主定理即可解出时间复杂度。