我需要一个算法,可以解析2D数组并返回最大连续矩形。请参考我制作的演示图像。
通常使用所谓的扫描线算法来解决这类问题。它们逐行(或扫描线)检查数据,以构建您要查找的答案,例如候选矩形。
以下是其大致工作原理:
将图像中的所有行从0..6编号,我将从下往上处理。
检查第0行,您有两个矩形的开头(假设您只关心黑色正方形)。我会使用(x、y、width、height)表示矩形。这两个活动矩形分别为(1,0,2,1)和(4,0,6,1)。将它们添加到活动矩形列表中。该列表按递增的x坐标排序。
现在已完成扫描线0,因此您要增加扫描线计数。
检查第1行,沿着该行工作,看看是否有以下情况:
沿着该行工作时,您会发现有一个新的活动矩形(0,1,8,1),我们可以将现有的一个活动矩形扩展为(1,0,2,2),并且需要用两个更窄的矩形代替活动矩形(4,0,6,1)。我们需要记住这个矩形,因为它是迄今为止最大的矩形。它被替换为两个新的活动矩形:(4,0,4,2)和(9,0,1,2)。
因此在第1次扫描结束后,我们有:
我认为一种区域生长的方法是很好的选择。
这可能是一种彻底但不是最有效的方法。
我想你需要回答哲学问题“一串点是一个细长的矩形吗?”如果一条线==一个瘦矩形,你可以进一步优化:
使用第一种方法检查你的工作。我想Knuth说过“过早地优化是万恶之源。”
希望对你有所帮助,
Perry
附言:经过几次编辑,我认为这个答案值得一起投票。
<=
检查,而不是一个 ==
检查。否则,你将会错过很多可能的矩形,包括可能是最大的矩形。此外,你仍然会重复做一些上下移动的工作。如果你删除组合后的元素,就可以避免这种情况(尽管使用 <=
检查,这会破坏一些情况)。一旦你开始尝试优化它,这个问题可能会变得非常复杂 :) - Merlyn Morgan-Grahamvar biggestFound
for each potential rectangle:
if area(this potential rectangle) > area(biggestFound)
biggestFound = this potential rectangle
for each square in grid:
recursive loop 1:
if not occupied:
grow right until occupied, and return a rectangle
grow down one and recurse (call loop 1)
总体复杂度为O(mn)。要了解更多信息,请阅读第15章或Cormen算法书的第15.4节。