Algorithm 求给定布尔数组中最大矩形区域的算法

Algorithm 求给定布尔数组中最大矩形区域的算法,algorithm,geometry,Algorithm,Geometry,所以问题本身很简单,每个输入,给我一个宽度和高度,都不会超过200,然后是一系列的0和1来表示二维平面 像这样 4 5 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 目标是在右侧找到面积为12的区域。不用说,矩形只能由1组成 我在写这篇文章的时候考虑过洪水填充,但它必须为数组中的每1重新计算。这个问题的最佳算法是什么?类似于下面的问题:找到和最大的子矩阵。这可以通过一个O(n^3)算法来实现。我相信你可以在stackoverflow上找到它,也可以在互联网上搜

所以问题本身很简单,每个输入,给我一个宽度和高度,都不会超过200,然后是一系列的0和1来表示二维平面

像这样

4 5
0 0 1 1 1
0 1 1 1 1
1 1 1 1 1
1 1 1 1 1
目标是在右侧找到面积为12的区域。不用说,矩形只能由1组成


我在写这篇文章的时候考虑过洪水填充,但它必须为数组中的每1重新计算。这个问题的最佳算法是什么?

类似于下面的问题:找到和最大的子矩阵。这可以通过一个O(n^3)算法来实现。我相信你可以在stackoverflow上找到它,也可以在互联网上搜索


对于这个问题,u可以用-INF替换0s,然后应用上述算法找到最大的矩形区域。

我能想到的最佳算法是遍历2D矩阵,从左上角开始,到右下角,在这种情况下,执行以下操作:

对于您找到的每一个1,查找最长的1的水平字符串以及垂直字符串。为了提高效率,右侧的位置比左侧的位置小1(您仍然需要获得其垂直最大值);您只需在每次遇到0时重新开始计数。当你到达下一行时,同样适用

两个数字的乘积是从该位置开始的矩形的最大可能面积。在另一个数据结构中,存储位置、maxWidth和maxHeight,并根据顶部面积最大的区域进行排序。避免放置子矩形以提高效率;可以通过忽略maxHeight小于或等于其自身值的右相邻1来完成此操作。我将数据结构的选择权留给您

现在,您将浏览您创建的数据结构,并从max矩形开始。找到最近的0。将矩形拆分为2个子矩形,其中不包括0所在的水平线,以及2个子矩形,其中不包括0所在的垂直线。如果0位于边上,则只能得到3个子矩形,如果它位于角上,则只能得到2个子矩形。删除矩形,插入新创建的子矩形,并保持最大面积顺序。现在对数据结构中的下一个矩形重复此过程,直到找到一个没有0的矩形。那是最大的一个


这应该比检查每个可能的子矩阵更有效。

有一些注释指向线性复杂度的答案,但我想我应该提到一个简单的O(n^2)算法

对于每个单元格,计算完全位于其下方和左侧的单元格数。您可以在线性时间内完成此操作,方法是从左下角开始按行操作,查看其下方的单元格,并查看其左侧单元格的小计

矩形可以由其左下角的点和右上角的点定义。当然,它有四个角。如果将之前计算的左下角和右上角的总数相加,再减去左上角和右下角的总数,则将得到矩形中的单元格数-矩形之外的单元格要么根本不计数,要么被取消。矩形的确切位置取决于你们在拐角处做什么,以及你们如何解释“完全在它下面,完全在它的左边”。但是,给定定义矩形的两个角,您可以通过检索四个数字并执行加减运算来计算其中的和

由两个点定义的矩形有O(n ^ 2)矩形要考虑(因为n取数据的大小,这意味着要搜索的区域有O(n)点)。由于我可以在固定时间内计算每个矩形内的总和,并丢弃那些没有总和的矩形,这意味着覆盖了所有点,因此总成本为O(n^2)。

/*
给定一个具有m行和n列的二维二进制数组(0和1的二维数组),查找最大子数组(矩形)的面积
完全由1组成。
*/
公共int findMaxRectangleArea(int[]A、int m、int n){
//m=行,n=列,根据问题
int[]单个;
int-largeX=0,最大值=0;
for(int i=0;ifindX){
findX=a;
混合=shrt;
}
}否则{
a=0;
}
}
a=findX;
a=(a==y)?a-1:a;
如果(a*y>largeX*max){//这里我用xy检查值
大x=a;
最大=y;
ii=i;
小=混合;
}
}
}//循环结束
返回大*最大;
}//方法结束
/*
时间复杂度=方法包含2个内循环,因此m*m&1个外循环n
所以复杂性是----------------->O((m^2)*n)
空间复杂度是------它与s成正比
 /*

Given a 2D binary array(2D array of 0's and 1's) with m rows and n columns,find area of largest sub-array(rectangle) 
consisting entirely of 1's.
*/

public int findMaxRectangleArea(int[][] A,int m,int n){
        // m=rows & n=cols according to question

        int[] single;
        int largeX = 0,largest = 0; 
        for (int i = 0; i < m; i++) {
              single = new int[n];            //one d array used to check line by line & it's size will be n
              for (int k = i; k < m; k++) {                // this is used for to run until i contains element
                        int a = 0;
                    int y = k - i + 1;  // is used for row and col of the comming array
                    int shrt = 0,ii = 0,small = 0; 
                                    int mix = 0;
                    int findX = 0; 
                   for (int j = 0; j < n; j++) {
                       single[j] = single[j] + A[k][j]; // postions element are added
                      if (single[j] == y) {           //element position equals
                            shrt = (a == 0) ? j : shrt;       //shortcut
                            a=a+1;
                        if (a > findX) {
                            findX = a;
                            mix = shrt;
                        }
                    } else {
                        a = 0;
                    }
                }
                   a = findX;
                   a = (a == y) ? a - 1 : a;
                         if (a * y > largeX * largest) {  // here i am checking the values with xy
                           largeX = a;
                           largest = y;
                           ii = i;
                           small = mix;
                           }
            }
        }// end of  loop

return largeX*largest;
    }       //end of method




/*
     Time complexity = method contains 2 inner loops so m*m & 1 outer loop n

     so the complexity is------------------->  O((m^2)*n)

     Space Complexity is-------it's directly proportional to the size of the array i.e ---------------> (m*m)+n

*/