给定一组 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
进行排序时将获得的y
s 数组中的非反转数。你可以负担得起这种排序 - 它是O(n log n)
。
我提醒你,反转是i
> j
和a[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)。可以看到负斜率是由 , , , 等。所有y
s 没有反转的对。
使用合并排序算法的增强,可以在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) 时间内找到它们之间具有负斜率的点对的数量?的主要内容,如果未能解决你的问题,请参考以下文章