一尘不染

在2D块网格中查找矩形

algorithm

假设我有一个7x12的块状网格。我们使用颜色“ *”,“%”,“ @”和空单元格“-”。

1 2 3 4 5 6 7
- - - - - - -  1
- - - - - - -  2
% % - - - - -  3
% % - - - - *  4 
% % - - - @ %  5
@ @ @ - - @ %  6
@ @ * * * - *  7
* * * % % % %  8 
% @ @ % * * %  9
% @ % % % % %  10
* * * % % @ @  11
* * @ @ @ @ *  12

我想在此网格中找到一定最小尺寸的矩形,然后找到最大的矩形,然后缩小,直到找不到大于或等于最小尺寸的矩形。

在此示例中,请考虑最小尺寸1x4、4x1、2x2,因此1x3无效,而2x3是有效的。如果我们想要最大的矩形,则可以找到以下内容:

  • 在(4,8)处为4x1
  • 5x1 at(3,10)
  • 2x3 at(1,3)
  • 2x2 at(6,1)
  • 2x2 at(1.11)
  • 4x1 at(3,12)

请注意,矩形不能在彼此之间的空间中,它们不能重叠。例如,未提及(4,10)处的2x2矩形,因为它将与(3,10)处的5x1矩形重叠。

所有都是完全有效的矩形:它们等于或大于最小大小,并且每个矩形的所有块都具有相同的颜色。

我想要以编程方式执行此操作。当您告诉某人在网格中查找矩形时,他会立即发现它们,而无需考虑它。问题是,我怎么能写出同样的算法?

我考虑过暴力破解,但是我需要算法尽可能快地执行,因为它需要在有限的(移动)设备上的非常短的时间内执行很多次。

我在互联网上看到很多有关矩形的问题,但令我感到惊讶的是,尚未有人问过这个问题。我是不是觉得太难了,还是没人愿意做这样的事情?


阅读 230

收藏
2020-07-28

共1个答案

一尘不染

分别调用输入数组W和H的宽度和高度。

  1. 运行这种聪明的O(WH)算法来确定最大的矩形,而不是仅跟踪单个最大的矩形,对于W * H矩阵中的每个(x,y)位置记录,其(一个或全部)的宽度和高度左上角为(x,y)的最大矩形,可以随时更新这些值。
  2. 循环遍历此矩阵,将矩阵中每个足够大的矩形添加到按面积(宽度*高度)排序的最大堆中
  3. 从该堆中读取条目;它们将以降序生产。读取每个条目的左上角为(x,y)且宽度为w和高度为h的条目时, 在W H位数组 中将矩形中包含 的w h个位置 标记 为“已使用” 。从堆中读取矩形时,必须丢弃任何包含“已用”正方形的矩形,以免产生重叠的矩形。只需对照“已用”数组检查每个候选矩形的 四个边缘 就足够了,因为候选矩形可以与另一个矩形重叠的唯一另一种方式是,如果后者完全包含在其中,则由于实际上,我们正在按递减的面积顺序读取矩形。

这种方法是“贪婪的”,因为如果有多种方法可以将纯色区域雕刻为最大矩形,则不能保证选择总体上最大的矩形序列。(例如,可能有几个矩形的左上角位于(10,10),其面积为16:16x1、8x2、4x4、2x8、1x16。在这种情况下,一种选择可能会产生较大的矩形“下游”,但我的算法不能保证做出选择。)如果有必要,您可以使用回溯找到矩形的总体最佳系列,尽管我怀疑在最坏的情况下这可能会很慢。

我提到的最大矩形算法是为单色矩形设计的,但是,如果您不能使其适应多色问题,则可以在开始步骤2之前为每种颜色运行一次。

2020-07-28