给定一组 n 个点 (x,y),是不是有可能在 O(n logn) 时间内找到它们之间具有负斜率的点对的数量?

Posted

技术标签:

【中文标题】给定一组 n 个点 (x,y),是不是有可能在 O(n logn) 时间内找到它们之间具有负斜率的点对的数量?【英文标题】:Given a set of n points (x,y), is it possible to find the number of pairs of points with negative slopes between them in O(n logn) time?给定一组 n 个点 (x,y),是否有可能在 O(n logn) 时间内找到它们之间具有负斜率的点对的数量? 【发布时间】:2013-05-02 06:35:02 【问题描述】:

给定(x,y)形式的二维平面上的一组n个点,目标是找到所有点(xi,yi)(xj, yj)的对数,使得连接这两个点的线具有负斜率。

假设没有两个xi 具有相同的值。假设所有点都在[-100,100] 或其他范围内。

【问题讨论】:

如何在 O(n logn) 时间内找到所有 O(n^2) 对点? 能找到计数吗? 正如你所说的 O(n logn) 是你正在寻找的东西,我想确保一件事它们以某种方式排序?? @ashudeep21:顺便说一句,分而治之是非常好的调用 asatag:这是我建议的合并排序。然而,问题不在于几何...... @Boris:是的......我现在也有同感。然而,我陷入了一个更大问题的这一部分,这似乎是几何密集型的。 【参考方案1】:

您所询问的内容相当于在您对x 进行排序时将获得的ys 数组中的非反转数。你可以负担得起这种排序 - 它是O(n log n)

我提醒你,反转是i > ja[i] a[j]。我所说的等价性很容易证明。

假设您有 6 个点 (4, 4), (2, 1), (6, 6), (3, 3), (5, 2), (1, 5)。根据x 对它们进行排序后,您将获得:(1, 5), (2, 1), (3, 3), (4, 4), (5, 2), (6, 6)。可以看到负斜率是由 , , , 等。所有ys 没有反转的对。

使用合并排序算法的增强,可以在O(n log n) 中计算反转的数量:基本上,每次选择添加正确子数组(包含较大索引的那个)的值时,您只需要增加反转的计数器。您可以根据左侧子数组中仍未处理的值的数量来增加反转次数。

这是计算反转次数的示例。

Initial array 5 1 3 4 2 6  inv := 0 // Total inversions: 6
merge step 1: <5 1 3> <4 2 6> inv = 0
merge step 2: <5> <1 3> | <4> <2 6> inv = 0
merge step 3: <5> [<1> <3>] | <4> [<2> <6>] inv = 0
merge step 4: <5> <1 3> | <4> <2 6> inv = 0 // both pairs were already sorted
merge step 5: <1 3 5> | <2 4 6> inv = 3 // we add one for 1, 3 and 2
merge step 6  <1 2 3 4 5 6> inv = 6 // we add 2 (3 and 5) for 2 and 1 for 4 

在找到反转数之后,对总数中的非反转数(n * (n - 1)) / 2 减去反转数inv

在示例中是:6 * 5 / 2 - 6 = 9

【讨论】:

以上是关于给定一组 n 个点 (x,y),是不是有可能在 O(n logn) 时间内找到它们之间具有负斜率的点对的数量?的主要内容,如果未能解决你的问题,请参考以下文章

给定一组点或向量,找到彼此最接近的 N 个点的集合

拉格朗日插值浅谈

Treepath

在给定一组坐标的情况下计算曲线下的面积,而不知道函数

91. 最短Hamilton路径

位运算 - 最短Hamilton路径