Algorithm 最大重叠矩形数

Algorithm 最大重叠矩形数,algorithm,Algorithm,我看过这个面试问题,不知道如何回答: 给定N个矩形,求重叠矩形的最大数目。 例如,对于由左下角和右上角点表示的矩形,[(1,1),(3,3)],[(2,2),(4,4)],[(1,3),(2,4)],[(2,2),(3,3)],返回3,因为前两个和最后一个矩形重叠。我可以想到一个时间复杂度为O(n^2)的算法,但应该有一个O(NlogN)的算法。根据要求,我的O(n^2)算法如下所示: 使用重复项对底部和顶部边缘的所有y轴值进行排序,在本例中,我们将得到(1、2、2、3、3、4)。此步骤给出了(

我看过这个面试问题,不知道如何回答: 给定N个矩形,求重叠矩形的最大数目。 例如,对于由左下角和右上角点表示的矩形,[(1,1),(3,3)],[(2,2),(4,4)],[(1,3),(2,4)],[(2,2),(3,3)],返回3,因为前两个和最后一个矩形重叠。我可以想到一个时间复杂度为O(n^2)的算法,但应该有一个O(NlogN)的算法。

根据要求,我的O(n^2)算法如下所示:

  • 使用重复项对底部和顶部边缘的所有y轴值进行排序,在本例中,我们将得到(1、2、2、3、3、4)。此步骤给出了(NlogN)时间复杂度。对于每个值,我们还需要记录它所属的矩形

  • 获取每个矩形左右边的所有x轴值(每个矩形的2N值,在本例中,我们将得到(1,2,3,4))。对于每个x值,我们创建一条穿过(x,0)的垂直线

  • 对于每个垂直线,迭代第一步中排序的所有值,计算在当前垂直线重叠的最大矩形数。我们可以通过扫描线算法在O(N)时间内完成(在我们的示例中,在值1处有一个矩形,然后转到值2,两个矩形相加,因此3个矩形重叠,在值3处,一个被相加,另一个向左,两个矩形重叠)。因此,总的来说,它将给出O(N^2)的时间复杂度


  • 为了找到最大重叠的数量,我们需要执行以下操作:

    • 将每个矩形分为两段,开放和结束,例如,对于矩形[(0,0)(1,1)]->我们可以使用两段[(0,0)(0,1)]和[(1,0),(1,1)]来表示它

    • 根据其x坐标对所有这些线段进行排序

    • 迭代这些段,并在维护段树以跟踪矩形的同时:

      • 如果线段是开放的,并且具有坐标(x,y1)(x,y2)->将线段树中的线段(y1,y2)增加1

      • 如果线段很近并且具有坐标(x,y1)(x,y2)->将线段树中的线段(y1,y2)减少一

    • 当我们遇到一个开放段(x,y1)(x,y2)时,我们还会检查段树中(y1,y2)中存在多少段,这些数字中的最大值就是最终结果


    请注意,段树中的每个添加/删除/搜索查询都是O(logn)->我们得到了一个O(nlogn)解决方案

    先发布你的解决方案,然后寻求优化帮助。我想不出一个O(NlogN)解决方案(但无论如何我不是算法专家…)。我可以想出一些替代方法来实现这一点,但不一定比O(n^2)暴力解决方案更好。除了你提供的样本数据外,我还想问面试官输入的数据一般是什么样的?e、 g.N能有多大?矩形能有多大?它们是[(1,1),(3,3)]-ish大小还是[(1000,1000),(30000000)]?请查看Lucanus Simonson的多边形包算法。他的实现是C++ Boost库的一部分。他开发了一种基于点的多边形演算,该演算将基本布尔运算(例如交集)简化为线性时间。这应该会有所帮助,尽管我还没有说服自己有一个简单的迭代来利用它来获得所需的解决方案。你知道它们吗?分段树是的,你能简单地解释一下这个想法,或者给我一些实现O(nlogn)的时间复杂度的参考资料吗?谢谢,这个解释很清楚而且非常有用。如何为这个问题创建分段树@phamHow如何根据上述逻辑创建段树?