You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中(0,1)矩阵的最大全零子矩形计数方法咨询

解决仅含0的极大子矩形计数问题

Hey there! Let's break down how to solve this problem—you've already got a solid start with your areAllZeros function, so we just need to add logic to identify those maximal zero rectangles (the ones that can't be wrapped inside any larger all-zero rectangle).

先明确什么是「极大子矩形」

As you defined it: a zero subrectangle is maximal if there's no larger all-zero rectangle that completely contains it. Put another way, it can't be expanded in any direction (up, down, left, right) while still staying entirely within zeros.

For your example matrix:

Row 0: 0 0 1 0 0 0 0 0
Row 1: 0 0 0 0 0 0 0 0

The 3 maximal rectangles are exactly the ones you listed because none of them can be expanded into a bigger all-zero rectangle without hitting a 1 or the matrix edge.

核心思路:判断矩形是否无法扩展

To check if an all-zero rectangle is maximal, we just need to verify that it can't be expanded in any direction:

  • Up: If there's a row above the rectangle, that row must have at least one 1 in the columns covered by the rectangle.
  • Down: If there's a row below, that row must have at least one 1 in the rectangle's columns.
  • Left: If there's a column to the left, that column must have at least one 1 in the rectangle's rows.
  • Right: If there's a column to the right, that column must have at least one 1 in the rectangle's rows.

If all these conditions are met, the rectangle can't be expanded into a larger all-zero rectangle, so it's maximal.

代码实现

First, let's add a helper function to check if a rectangle is maximal:

static boolean isMaximal(int[][] matrix, int top, int left, int height, int width) {
    int rows = matrix.length;
    int cols = matrix[0].length;
    int bottom = top + height;
    int right = left + width;

    // Check if we can expand upward
    if (top > 0) {
        boolean hasOne = false;
        for (int j = left; j < right; j++) {
            if (matrix[top - 1][j] == 1) {
                hasOne = true;
                break;
            }
        }
        if (!hasOne) return false;
    }

    // Check if we can expand downward
    if (bottom < rows) {
        boolean hasOne = false;
        for (int j = left; j < right; j++) {
            if (matrix[bottom][j] == 1) {
                hasOne = true;
                break;
            }
        }
        if (!hasOne) return false;
    }

    // Check if we can expand leftward
    if (left > 0) {
        boolean hasOne = false;
        for (int i = top; i < bottom; i++) {
            if (matrix[i][left - 1] == 1) {
                hasOne = true;
                break;
            }
        }
        if (!hasOne) return false;
    }

    // Check if we can expand rightward
    if (right < cols) {
        boolean hasOne = false;
        for (int i = top; i < bottom; i++) {
            if (matrix[i][right] == 1) {
                hasOne = true;
                break;
            }
        }
        if (!hasOne) return false;
    }

    // Can't expand in any direction—this is a maximal rectangle
    return true;
}

Then, we'll write the main function to count all maximal rectangles, with some optimizations to avoid unnecessary checks:

static int countMaximalZeroRectangles(int[][] matrix) {
    if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
        return 0;
    }
    int rows = matrix.length;
    int cols = matrix[0].length;
    int count = 0;

    // Iterate all possible top-left corners
    for (int top = 0; top < rows; top++) {
        for (int left = 0; left < cols; left++) {
            // Skip if starting cell is 1—no all-zero rectangle can start here
            if (matrix[top][left] != 0) {
                continue;
            }

            // Iterate all possible heights (from 1 to remaining rows)
            for (int height = 1; height <= rows - top; height++) {
                int bottom = top + height;
                // If the bottom row's left cell is 1, taller heights will also include this 1—break early
                if (matrix[bottom - 1][left] != 0) {
                    break;
                }

                // Iterate all possible widths (from 1 to remaining columns)
                for (int width = 1; width <= cols - left; width++) {
                    int right = left + width;
                    // If the right column's top cell is 1, wider widths will also include this 1—break early
                    if (matrix[top][right - 1] != 0) {
                        break;
                    }

                    // Check if this subrectangle is all zeros
                    if (areAllZeros(matrix, top, left, height, width)) {
                        // Check if it's maximal
                        if (isMaximal(matrix, top, left, height, width)) {
                            count++;
                        }
                    } else {
                        // Wider widths will also have non-zero cells—break early
                        break;
                    }
                }
            }
        }
    }
    return count;
}

测试你的示例

Let's test this with your sample matrix:

public static void main(String[] args) {
    int[][] matrix = {
        {0, 0, 1, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0}
    };
    System.out.println(countMaximalZeroRectangles(matrix)); // Output: 3
}

This will print 3, which matches your expected result.

注意事项

  • This approach works well for small to medium-sized matrices. For very large matrices, you might want to look into more optimized algorithms (like using histogram-based methods to find all maximal rectangles in linear time relative to the matrix size), but this implementation is straightforward and easy to understand.
  • Make sure to handle edge cases, like empty matrices or matrices with no zeros at all (which will return 0).

内容的提问来源于stack exchange,提问作者not_founded

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:17:40