[leetcode]Maximal Rectangle

本文介绍了LeetCode上的最大矩形问题的两种解决方案。思路一是通过遍历矩阵找到所有可能的最大全1矩形区域;思路二是利用直方图最大矩形的解法,先构建每个元素向下连续1的数量,再应用到每行中找出最大矩形面积。

from : https://leetcode.com/problems/maximal-rectangle/

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

思路1:

遍历i,j,当这个位置为1,则以之为矩形左上角,遍历以这个点为左上角的矩形,更新最大面积。

public class Solution {
    public int maximalRectangle(char[][] matrix) {
        if(matrix==null || matrix.length==0) {
            return 0;
        }
        int max = 0;
        int m=matrix.length, n=matrix[0].length;
        boolean[][] isOne = new boolean[m][n];
        
        for(int I=0; I<m; ++I) {
            for(int J=0; J<n; ++J) {
                if( isOne[I][J] = (matrix[I][J]=='1') ) {
                    // I, J is '1'
                    for(int i=I; i<m; ++i) {
                        for(int j=J; j<n; ++j) {
                            // find boundry
                            if(i == I && j == J) {
                                // continue;
                            } else if(i == I) {
                                isOne[i][j] = isOne[i][j-1] && (matrix[i][j] == '1');
                            } else if(j == J) {
                                isOne[i][j] = isOne[i-1][j] && (matrix[i][j] == '1');                             } else {
                                isOne[i][j] = isOne[i-1][j] && isOne[i][j-1] && matrix[i][j] == '1';
                            }
                            if(isOne[i][j]) {
                                int a = (i-I+1)*(j-J+1);
                                max = a>max ? a : max;
                            } else {
                                break;
                            }
                        }
                    }
                }
                
            }
        }
        
        return max;
    }
}


思路2:

借用leetcode的Largest Rectangle in Histogram。求出每行下面的直方图,然后计算。解法见Largest Rectangle in Histogram

public class Solution {
    private Stack<Integer> idxes = new Stack<Integer>();
    public int maximalRectangle(char[][] matrix) {
		if (matrix.length == 0 || matrix[0].length == 0) {
			return 0;
		}
		int m = matrix.length;
		int n = matrix[0].length;
		int max = 0;
		int[][] grid = new int[m][n];
		for(int i=0; i<m; ++i) {
		    for(int j=0; j<n; ++j) {
		        int k=i;
		        while(k < m && '1' == matrix[k][j]) {
		            k++;
		        }
		        grid[i][j] = k-i;
		    }
		}
		for(int i=0; i<m; ++i) {
		    max = Math.max(maxHistogram(grid[i]), max);
		}
		return max;
    }
    private int maxHistogram(int[] height) {
        int max = 0, len=height.length;
        for(int i=0; i<len;) {
            if(idxes.empty() || height[idxes.peek()] <= height[i]) {
                idxes.push(i);
                ++i;
            } else {
                int idx = idxes.pop();
                int width = idxes.empty()? i : i-1-idxes.peek();
                max = Math.max(max, width*height[idx]);
            }
        }
        while(!idxes.empty()) {
            int idx = idxes.pop();
            int width = idxes.empty()? len : len-1-idxes.peek();
            max = Math.max(max, width*height[idx]);
        }
        return max;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值