一种O(n * log(n))算法,用于找到具有最低斜率的段(在n * n个段中)

时间:2012-08-29 22:11:44

标签: algorithm computational-geometry lines points

给定 n 的不同点的 P = {p 1 ,...,p n } 2 行,编写一个算法,在最坏的情况下找到具有最低斜率(最小绝对值)且具有O(n*log(n))时间复杂度的行。

2 个答案:

答案 0 :(得分:6)

根据y位置对点进行排序(使用任意数量的众所周知的算法,n log n time)。按顺序浏览列表,从0到n - 1,比较每个点对的斜率与您发现的任何斜率到目前为止的最低斜率。 (那是时间)。

总的来说,那就是O(n log n)。

在伪代码中:

Let P be the list of points (this list starts at 1)
n = P.length
S = quicksort("a.y < b.y", P) // or some other O(n log n) algorithm
bestSlope = float.inf
let p1 and p2 be points
for i = 1 to n-1:
    currSlope = abs((P[i].y - P[i+1].y) / (P[i].x - P[i+1].x))
    if currSlope < bestSlope:
        bestSlope = currSlope
        p1 = P[i]
        p2 = P[i+1]

答案 1 :(得分:6)

定理:

  • 给出一组点P。
  • 在P中选择两个点A和C,使得AC线具有最小的绝对斜率(如问题中所定义)。
  • 对于多对点具有相同斜率的退化情况,让AC成为具有该斜率的最短线段。
  • 然后P中没有其他点,A和C之间有Y坐标。

证明(矛盾):

  • 假设至少有一个其他点B,其Y坐标介于A和C之间。
  • 然后存在三种可能的情况:
    • B与A和C共线。然后,线AB或BC具有与AC相同的斜率,但它们的两个都比AC短。矛盾。
    • B落在“AC”上方的半平面上。然后,线AB具有比AC更浅的斜率。矛盾。
    • B落在“AC”下方的半平面上。然后,线BC具有比AC更浅的斜率。矛盾。
  • 所有情况都会导致矛盾,因此A和C之间不会出现任何分数。
  • QED。

根据这个定理,您可以清楚地使用@ Zshazz算法找到正确的对 - 因为它们将是最近邻居 - O(n*log n)