查找边框上包含类似单元格的最大子矩阵

时间:2012-11-02 22:20:08

标签: algorithm matrix

问题是,给定所有单元格为黑色或白色的矩阵,找到所有边界单元格为黑色的最大尺寸子矩阵(内部单元格不需要为黑色)。

目前,我充其量只能考虑O(N^4)解决方案。为此,我制作了两个辅助表,一个用于每个单元的每行中右边连续黑色单元的计数,另一个用于每个单元的该列中连续黑色单元的计数。然后我这样做:

for each row (i):
   for each cell (i,j):
     for each window (1..n-j):
       if auxrow[i,j+window]-auxrow[i,j] == window:   #so, all cells in this window is black
         colsleft = auxcol[i,j]
         colsright = auxcol[i,j+window]
         botttom_row = min(colsleft,colsright)
         for bot in (row..row+mincol):
            if auxrow[bot][j+window]-auxrow[bot][j] == window:
              maxlen = ... #do whatever to save this sub-matrix as answer

如何改进此解决方案?我在Topcoder看到了一些有趣的讨论,特别是Rem(O(N^2*log N))的答案,以及Tomek提出的后续改进,但我无法理解这两种解决方案!有人可以提供比我更好的解决方案,或解释这些算法吗?

1 个答案:

答案 0 :(得分:3)

O(N ^ 3)是可能的。

对于每个单元格,计算顶部和右侧的连续黑色单元格(可以在O(N ^ 2)时间内完成。)

对于每一列(比如第i列),您将获得一个包含n个元素的数组,这些元素保留了正确的信息,例如R_i。

现在给定数组R_i,我们计算n个其他数组(所以Omega(N ^ 3)空间)如下:

对于每个d,使得1< = d< = n,你创建一个新的n个元素数组D_id,如果R_i中的对应值,即元素j,则n + 1,即R_i [j] < d。如果R_i [j]> = d,则D_id中的对应条目将等于j。

基本上给定d和i,使用数组D_id,我们可以告诉第i列中的哪个单元格可能是宽度为d的矩形的端点。

现在预处理每个D_id以进行范围最小化查询:即给定范围[u,v],我们可以在O(1)时间内找到子数组D_id [u ... v]中的最小值。

由于您为每列花费O(N ^ 2)时间,因此此步骤为O(N ^ 3)时间。

现在找到一个矩形,你可以考虑每一行并选择每一对可以用于矩形的一个边的点。将这些点视为矩形的左下角和右下角。

假设考虑的点在列i和j上,矩形的宽度为d。

现在找到矩形的最大可能高度(使用我们之前计算的顶部值)。说它是h。

现在,如果你考虑的行是r,你现在在范围(r,rh)上对D_id运行范围最小查询。如果最小值是< = n,那么你找到了一个矩形。

由于你会考虑N ^ 3个这样的可能对(每行N ^ 2个点),总运行时间为O(N ^ 3)。