以下是我努力解决的面试问题。所需的界限应小于O(n^2)
。这是问题所在:
您获得了一组积分S =
(x1,y1)....(xn,yn)
。要点 是XY平面上的坐标。据说点(xa,ya)
当且仅当(xb,yb)
和xa > xb
时,大于ya > yb
点。 目标是从集合S中找到所有点对p1 =(xa,ya)和p2 =(xb,yb),使得p1> 1。 P2
示例:
Input S = (1,2),(2,1),(3,4)
Answer: {(3,4),(1,2)} , {(3,4),(2,1)}
我只能想出一个O(n^2)
解决方案,其中涉及用其他点检查每个点。如果有更好的方法,请帮助我。
答案 0 :(得分:3)
我不确定你能做到。
示例案例:让点为(1,1),(2,2)......(n,n)。
有O(n ^ 2)个这样的点并输出它们本身需要O(n ^ 2)时间。
答案 1 :(得分:2)
我假设您实际上想要计数这样的对。
按x
中的O(n log n)
降序排序。现在我们已将问题缩小到一个维度:对于每个位置k
,我们需要计算在大于位置k
处的数字之前的数量。这相当于计算反转,这个问题已在本网站上多次回答,包括我,例如here。
获取O(n log n)
问题的最简单方法是使用合并排序算法,如果您想在点击该链接之前自己考虑一下。其他方式包括使用二进制索引树(fenwick树)或二叉搜索树。实践中最快的可能是使用二进制索引树,因为它们只涉及按位操作。
如果您想打印对,在最坏的情况下,您不能比O(n^2)
做得更好。不过,我也会对输出敏感的O(num_pairs)
算法感兴趣。
答案 2 :(得分:0)
为什么不用X和Y作为二级索引对点列表进行排序? (的 O(nlogn)强>)
然后你可以给出一个“懒惰”指标,显示每个点的右边所有点都比它大。
如果你想找到它们,那么无论如何都需要 O(n ^ 2),因为它有 O(n ^ 2)对。
想想一个排序列表,第一个是最小的,所以有n-1个更大的点,第二个有n-2个更大的点...加起来大约是(n ^ 2)/ 2 == <强>为O(n ^ 2)强>