如何在0和1的2D矩阵中找到矩形的数量?

时间:2017-04-09 00:28:52

标签: java arrays algorithm

我已在SO上搜索了一些帖子以及其他在线资源。他们中的大多数提供了在2D矩阵中找到矩形的最大面积的解决方案,我理解。但是,我很想知道你在2D矩阵中找到矩形数量的方法,其中矩形由1s 表示。

更新 为没有说明分类为矩形的场景而道歉 - 如果某个周界内的单元格已填充且为1,则将其视为矩形。

2 个答案:

答案 0 :(得分:2)

一些伪代码:

for x_0 in rows:
    for x_1 > x_0 in rows:     # symmetry-reduction: x_0 always "top"
        for y_0 in columns:
            for y_1 > y_0 in columns:  # symmetry reduction: y_0 always "left"
                if mat[x_0, y_0] == mat[x_0, y_1] == mat[x_1, y_0] == mat[x_1, y_1] == 1:
                    found rectangle!

请记住:它的伪代码(部分基于python风格),布尔评估在大多数语言中都不像那样!

对称性降低不仅可以提高性能,而且在计算时也很重要。视觉上相等的矩形,其中x_0和x_1只扮演不同的角色(左右点)。你必须决定如何计算它。

编辑:在Ole V.V。的评论之后,我意识到确实存在非常不同的解释。其中大部分可以通过上面的伪代码实现,但对内层有不同的检查。但那可能是你的工作(并且在某些情况下可以采用更多调整的方法)!

这里我假设,一个矩形只是由4个角的1来定义!

修改:在新定义矩形后,内部检查更改为:

if all(mat[x_0:x_1, y_0:y_1])  # python/numpy inspired pseudo-code!

所以基本上你可以检查4个边界点定义的所有值。这很容易解决你的问题。

但当然你可以更有效率。添加一些二进制标志可能是明智的,它指示当前矩形(它们正在增长)是否仍然仅填充1。实际上你可能需要2个二进制标志,每个维度1个。如果情况并非如此,那么你可以提早停止。

答案 1 :(得分:0)

这是一个非优化版本,应该给出正确的结果:

int sum = 0;
for (int row = 0; row < n; row++) {
    for (int col = 0; col < m; col++) {
        // count all rectangles with top left corner at (row,col)
        int upperLimit = m; // this number sets the max width that rectangles with greater
                            // height can have (depends on the 1s in the rows above)
        for (int r = row; r < n && matrix[r][col] == 1; r++) {
            int c = col;
            for (; c < upperLimit && matrix[r][c] == 1; c++)
                sum++;
            upperLimit = c;
        }
    }
}