📌  相关文章
📜  全为 1 的最大大小矩形二进制子矩阵(1)

📅  最后修改于: 2023-12-03 15:36:45.776000             🧑  作者: Mango

全为 1 的最大大小矩形二进制子矩阵

在计算机科学领域中,矩阵问题是一类常见的问题。其中,寻找全为 1 的最大大小矩形是其中的一种问题。

问题描述

给定一个二维矩阵,其中的元素都是 0 或 1。请找到一个矩阵子集,其中所有元素都是 1,并且这个子集所占据的行数与列数的积最大。换句话说,你需要找到矩阵中全为 1 的最大大小子矩阵。

样例

输入:

[
    [1, 0, 1, 0, 0],
    [1, 0, 1, 1, 1],
    [1, 1, 1, 1, 1],
    [1, 0, 0, 1, 0]
]

输出:

6

解释: 最大的矩形子矩阵中元素均为 1,所占据的行数为 3,列数为 2,积为 6。

解法

在解决这个问题的过程中,我们需要用到栈这个数据结构。具体步骤如下:

  1. 针对每一行,进行一次扫描。我们需要使用动态规划的方法计算出每一个位置上方连续的 1 的数量。
  2. 对于每一行,将其上方连续的 1 的数量作为一个数组存储。
  3. 针对每一行,使用这个数组作为输入,计算得出全为 1 的最大大小矩形,并且更新结果。
  4. 最终,我们得到的结果就是矩阵中全为 1 的最大大小子矩阵的大小。
代码实现

这里是 Java 语言的代码实现:

public int maximalRectangle(char[][] matrix) {
    if (matrix.length == 0) {
        return 0;
    }

    int maxArea = 0;
    int[] heights = new int[matrix[0].length];
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[0].length; j++) {
            if (matrix[i][j] == '1') {
                heights[j]++;
            } else {
                heights[j] = 0;
            }
        }
        int area = largestRectangleArea(heights);
        if (maxArea < area) {
            maxArea = area;
        }
    }
    return maxArea;
}

private int largestRectangleArea(int[] heights) {
    Stack<Integer> stack = new Stack<>();
    int maxArea = 0;
    int i = 0;
    while (i <= heights.length) {
        int h = (i == heights.length) ? 0 : heights[i];
        if (stack.isEmpty() || h >= heights[stack.peek()]) {
            stack.push(i++);
        } else {
            int top = stack.pop();
            maxArea = Math.max(maxArea, heights[top] * (stack.isEmpty() ? i : i - stack.peek() - 1));
        }
    }
    return maxArea;
}
参考资料
  • https://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html
  • https://leetcode.com/problems/maximal-rectangle/discuss/29064/A-O(n2)-solution-based-on-Largest-Rectangle-in-Histogram