给定一个坐标列表,我想知道如何知道在其他两个点的中间有多少点。
A(1 ; 3)
B(2 ; 2)
C(3 ; 1)
D(3 ; 2)
E(3 ; 3)
这是一个代表:
_______
|A| |E|
_______
| |B|D|
_______
| | |C|
_______
这里B和D是中点,所以答案是“2”。
我发现了一种非常低效的O(n³)
算法。
count := 0
For each point x1
For each point x2
For each point x3
If x3 is the midpoint of [x1;x2]
count := count + 1
Print count
您对更有效的算法有什么想法吗?
答案 0 :(得分:3)
使用 k-d tree ,您可以将其改进为O(n^2 logn)
:
将每个点存储在树中,对于每对(其中有O(n^2)
个),搜索它们中间是否存在一个点(很容易计算中间的位置)。每次搜索都是O(logn)
,导致O(n^2 * log(n))
解决方案。
如果您只讨论整数,则可以通过将点放在 hash table 中来平均将复杂度提高到O(n^2)
(作为对),并检查是否存在具有所需坐标的元素。
(注意,这两个解决方案基本相同,唯一的变化是集合的实现,一个使用树,另一个使用哈希表)。
伪码:
set <- new set
for each point p:
set.add(p)
for each point p1:
for each point p2 != p1:
candidate <- findMiddle(p1,p2)
if set.contains(candidate):
yield (p1,candidate,p2)