给出一个列表矩形[R1,R2,R3],它们由其左下角和右上角[(x1, y1), (x2, y2)]
坐标定义,并且值为k。
有没有找到k个矩形重叠的区域的最佳方法?
例如:
R1: [(1, 1), (5, 5)]
R2: [(4, 4), (7, 6)]
R3: [(3, 3), (8, 7)]
rectangles = [R1, R2, R3]
k = 2
被两个矩形重叠的区域是8。
解决该问题的蛮力方法是计算x轴和y轴坐标的最小值和最大值,然后使用它创建一个网格并为矩形内的每个单元格增加一个。最后,在网格上迭代以计算值为k的像元数量以找到解。
该方法的复杂度为O(n^3)
,假设每个矩形的大小为n x n
,并且有n个矩形。
是否有运行时最佳方法来解决此问题?
答案 0 :(得分:0)
将矩形插入数据结构,在其中按其底部坐标x1对其进行排序。使用例如一个自平衡的二叉搜索树,其复杂度为O(N.LogN),并允许以O(N)的顺序遍历该树,其中N为矩形的数目。在示例中,将是:
[R1, R3, R2]
在将矩形插入树中时,还保留所有唯一的上下坐标y1和y2的排序列表。在示例中,将是:
[1, 3, 4, 5, 6, 7]
现在,我们将两个连续的y坐标之间的每个水平切片视为一维问题(类似于this answer中的第一种方法)。
从矩形树的开始遍历此切片中的所有矩形(请记住,矩形按y1排序,因此它们在开始时被分组在一起),并为其唯一的x坐标创建了排序列表,并为每个值加上一个值(如果是左坐标,则加1),如果是右坐标,则减1。如果遇到矩形的顶部坐标等于切片的顶部坐标的矩形,请将其从矩形树中删除,这可以在O(1)中完成。对于示例中的第一个切片,y = 1〜3,高度为2,应为:
[1: +1, 5: -1]
如果我们对其进行迭代,则会发现一个宽度为4(因此为面积8)的区域,该区域是1个矩形的一部分。
对于示例中的第二个切片,y = 3〜4,高度为1,将为:
[1: +1, 3: +1, 5: -1, 8, -1]
如果我们对其进行迭代,我们将找到宽度2的区域(因此是区域2),它是1个矩形的一部分;宽度2的区域(因此是区域2),它是2个矩形的一部分,以及一个区域宽度3(因此是区域3)的宽度(1个矩形的一部分)。因此,属于k个矩形的任何区域都将添加到总计中。等等。
创建矩形树是O(N.LogN),创建切片列表是O(N.LogN),在切片上进行迭代是O(N),并且在每个切片内创建排序的x坐标列表是O( N.LogN),总共为O(N 2 .LogN),与矩形的大小,总面积的大小以及矩形的矩形或簇之间的重叠程度无关矩形。
答案 1 :(得分:0)
分析矩形集合的常用方法是使用扫掠线算法。想象一条垂直线从集合的左侧开始,然后向右扫描。存储当前与线相交的一组矩形,该矩形最初为空。当线通过任何矩形的垂直边时,需要更新此集合:在每种情况下添加或删除矩形。为了提高扫描效率,请使用垂直的x坐标的排序列表。
在这种情况下,您还需要一种方法来有效确定被k个或更多矩形覆盖的扫描线的间隔。这可以通过维护间隔树来有效地完成。
根据细节,对于n个矩形,效率应该大约为O(n log n),其中最大重叠深度可能需要附加术语。我会让你弄清楚细节。