你给出了平面上N个不同点的坐标(x,y)。计算用给定点形成的锐角三角形。蛮力很简单,但它的复杂性是二项式系数(n,3)。有没有人有更快的想法?
答案 0 :(得分:1)
这是我的解决方案:
从一个点p1
开始。现在,找到由当前点和所有其他点形成的线的斜率。相应地对点进行排序。
考虑此数组中的第一个点a1
。让斜率用m
表示。现在,找到垂直于该直线的直线斜率。
m_p = tan-1 ( 90 + tan(m))
对数组中的m_p
执行二进制搜索,并获取该斜率小于或等于m_p
的索引。这给出了形成锐角的元组计数,其中两个点是p1
和a1
。现在,考虑数组中的下一个点并执行相同的操作。
对每一点重复上述步骤。
时间复杂度分析:
用于排序:O(NlogN)
二进制搜索:logN
。在数组中的每个点上重复此操作需要O(NlogN)
为每个点重复上述步骤:
O(N * NlogN)= O(N 2 logN)
修改强>
我认为tan
正在增加(0,2*PI)
范围内的功能。最好找到每条线与正x-axis
形成的角度,然后将这些值排序为w.r.t这些值。现在,考虑每个点pi
,角度ai
和ai+90
之间的点数。当您考虑这些点时,在主点处形成的角度始终是锐角。
无论角度如何,这都将涵盖所有情况。
编辑2:
我的解决方案只有一半是正确的。它只能确保主点处的角度是锐角。但不保证在其他两点。
除了上述程序之外,您需要做的是为每个点形成另一组点(xi,yi)
。其中xi
表示主点和x轴之间的线的角度,yi
表示主点和当前点之间的距离。
使用这些新的点集构造kd树。现在,对于每个点ai
,在kd树中搜索角度位于mi
和mi+90
之间且距离介于0
和{{1}之间的点}。
这个额外的约束迫使其他两个角度变得尖锐。我把它留作练习来解决它。
现在时间复杂度为: O(N 2 logN)平均情况和 O(N 3 )在最坏的情况下(因为我们正在使用的kd-tree)。