#最大子矩阵的大小的Java实现

最大矩阵问题指的是在一个1组成的矩阵中,找到只包含1的最大矩形。以下是几种常见的Java实现方法:

方法一:基于直图的最大矩形面积(推荐

这种方法将问题转化为方图的最大矩形问题。

import java.util.Stack;

public class MaximalRectangle {
    public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }
        
        int m = matrix.length;
        int n matrix[0].;
        int[] heights = new int[n];        int maxArea = 0;
        
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') {
                    heights[j] 1;
                } else {
                    heights[j]0;
                }
            }
            maxArea = Math.max(maxArea,RectangleArea());

        
return maxArea;
    }
    
    private int largestRectangleArea(int[] heights) {
        Stack<Integer> stack = new Stack<>();
        int maxArea = 0;
        int n = heights.length;
        
        for (int i = 0; i <= n; i++) {
            int h = (i == n) ? 0 : heights[i];
            while (!stack.isEmpty() && h < heights[stack.peek()]) {
                int height =[stack.pop()];
                int width = stack.isEmpty() ? i : i - stack.peek() - 1;
                maxArea = Math.max(maxArea, height * width);
            }
            stack.push(i);
        }
        
        return maxArea;
    }
}

方法二:动态规划方法

这种方法使用三个动态规划数组来记录高度、左边界和右边界。

public class MaximalRectangle    public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }
        
        int m = matrix.length;
        int n = matrix[0].length;
        int[] heights = new int[n];
        int[] left = new int[n];
        int[] right = new int[n];
        Arrays.fill(right, n);
         maxArea =0;
        
        for (int i = 0; i < m; i++) {
            // 计算高度
            for (int j = 0; j < n; j++) {
                heights[j] = matrix[i][j] == '1' ? heights[j] + 1 : 0;
            }
            
            // 计算左 = 0;
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') {
                    left[j] = Math.max(left[j], boundary);
                } else {
                    left[j] = 0;
    boundary = j + 1;
                }
            }
            
            // 计算右边界
            boundary = n;
            for (int j = n - 1; j >= 0; j--) {                if (matrix[i][j] == '1') {
                    right[j] = Math.min(right[], boundary);                 {
                    [j] = n;
                    boundary = j;
                }
            }
            
            // 计算面积
            for (int j = 0; j < n; j++) {
                maxArea = Math.max(max (right[j - left[j]) * heights[j]);
            }
        }
        
        return maxArea;
    }
}

方法三:暴力法(不推荐,仅用于理解)

这种方法时间复杂度较高,易于理解。

public class MaximalRectangle {
    public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }
         =length;
        int n = matrix[0].length;
        int maxArea = 0;
        
        for (int i = 0; i; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') {
                    int area = expand(matrix, i, j,, n);
                     = Math.max(maxArea, area
                }
            }
        }
        
        return maxArea;
    }
    
    private int expand(char[][] matrix, int row, int col, int m, int n) {
        int maxRow = row;
        int minCol = col;
        int maxCol = col;
        int area = 0;
        
        while (maxRow < m && matrix[maxRow][col == '') {
             c;
            while (c >= 0 && matrix[maxRow][c] == '1') {
                c--;
            }
            minCol = Math.min(min1);

             col;
            while (c < n && matrix[maxRow][c] == '1') {
                c++;
            }
            maxCol = Math.max(max, c - 1);
            
            area = Math.max(area, (maxRow - row + 1) * (maxCol - minCol + 1));
            maxRow++;
        }

        return    }}

使用方法

public static void main(String[] args) {
    char[][] matrix = {
        {'1', '0', '1', '0', '0'},
        {'1', '0', '1', '1', '1'},
        {'1', '1', '1', '1', '1'},
        {'1',', '', '1 '0'}
    };
    
    MaximalRectangle solution = new MaximalRectangle();
    System.out.println("最大子矩阵面积: " + solution.maximalRectangle(matrix)); 输出6
}

复杂度分析

  1. 基于直方图的方法

    • 时间复杂度:O(m*n),其中m是行数,n是列数
    • 空间:O()
  2. 动态规划方法

    • 时间复杂度:O(m*n)
    • 空间复杂度:O(n)
  3. 暴力

    • 时间复杂度:O(m²*²)(不用于大规模数据)
    • 空间复杂度:O(1)

推荐使用基于直方图的方法或动态规划方法,它们在大规模数据上表现更好。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐