如何找到能够快速形成正斜率线的点数?

时间:2012-04-28 14:53:44

标签: algorithm

给定n对点,我们如何得到能够形成具有正斜率的线的点对的数量?

然后有n行,其中第i行包含两个整数xi和yi,指定第i个点的x和y坐标。没有两个点具有相同的x坐标,并且没有两个点具有相同的y坐标。

我的想法是首先对x进行排序,然后将每个点与其下方的另一个点进行比较。 但它仍然是O(n ^ 2)

2 个答案:

答案 0 :(得分:4)

选择一个点(随机是最简单的并且具有良好的预期运行时间,尽管您可以在线性时间内确定性地找到中间点),将轴分成四个象限:

  x        |
           |   x   x
     x     |  x
-----------x-----------
  x        |
   x       |      x
           | x

从左上角按IIIIIIIV表示逆时针方向的象限:

II  | I
----|----
III | IV

我们将忽略位于轴上的点(理论概率为0的边缘情况,并且很容易处理)。

请注意,象限III中的所有点都与I中的所有点形成正斜率线,同样地,来自II的点不会形成p。 IV中带点的线,所以我们递归调用:

NumPSLines(G) = |I|*|III| +
                NumPSLines(I U II) +
                NumPSLines(II U III) +
                NumPSLines(III U IV)

U表示联合。

假设(证明留给读者)期望E(|I|) = ... E(|IV|) = |G|/4 = n/4并且分区到象限是线性的,那么我们得到预期的运行时间:

T(n) = O(n) + 3T(n/2)
     = O(n) + ... + 3^k * t(n/2^k) // where k = log2(n)
     = O( log2(n) * 3^log2(n) )
     = O(n^(log2(3)) * logn)
     ~ O(n^1.6 * logn)

不确定这个界限是否紧张;没想过太多。

这个解决方案可以超级优化,虽然它是一个开始。

答案 1 :(得分:3)

按x递减排序,然后计算y中的反转次数。这两个步骤都是O(n log n)。

说明:具有正斜率的(无序)对的数量是对{(xi,yi),(xj,yj)}的对数,使得xi> 1。 xj和yi&gt; YJ。当我们按x降序排序时,我们将其设为xi&gt; xj当且仅当我&lt;学家ys中的反转的定义是一对i <1。 j使得yi> YJ。

Counting the number of inversions quickly.