Leetcode 85:最大矩形

问题

Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing only 1’s and return its area.
Example:
Input:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
Output: 6

分析

首先分享一个傻叉思路,当然这个思路由于超时而告终。

暴力动态规划:

遍历二维矩阵中的每一个元素;针对该位置,向四个方向进行矩形扩展;扩展过程中,记录当前可构成矩形的行和列的范围,即rowstart,rowend,colstart和colend;
递归终止条件:扩展超出matrix边界,或不能组成矩形。
以当前构成矩形的范围为rowstart,rowend,colstart和colend,向上扩展为例:rowstart=rostart-1;
1)若rowstart<0,end;
2)若matrix在colstart——colend范围内,存在元素!=‘1’,表示该次扩展尝试失败,end。
最后比较四个方向扩展的面积,取最大者返回。
时间复杂度:O(m2n2);(啊不会分析,可能比这个高)
空间复杂度:emmm

基于最大矩形面积:

https://leetcode.com/problems/maximal-rectangle/discuss/29055/My-java-solution-based-on-Maximum-Rectangle-in-Histogram-with-explanation
对于矩阵matrix,我们一行行的来看,截止到当前行,能够组成的最大矩形。
(啊不知道怎么解释)
row[]数组:记录截止到当前行,各列的最大高度。
遍历时的规则是:如果matrix[i][j]==‘1’(注意是字符矩阵),则row[j]=row[j]+1;(即在之前的基础上增加)否则,row[j]=0;
这个规则的原因是:记录截止到当前行,各列的1组成的最大高度。
以问题中的matrix为例,遍历所有行之后,一次得到的row为:

[“1”,“0”,“1”,“0”,“0”], --> [1,0,1,0,0], 相当于组成了高度为1,0,1,0,0的一个矩形序列
[“1”,“0”,“1”,“1”,“1”], --> [2,0,2,1,1] 相当于组成了高度为2,0,2,1,1的一个矩形序列
[“1”,“1”,“1”,“1”,“1”], --> [3,1,3,2,2]
[“1”,“0”,“0”,“1”,“0”] --> [4,0,1,3,0]

代码

暴力动态规划

    public int maximalRectangle(char[][] matrix) {
    	int ans=0;
    	int curr=1;
    	if(matrix==null||matrix.length==0) return 0;
    	int rowNum=matrix.length;
    	int colNum=matrix[0].length;
    	for(int i=0;i<rowNum;i++){
    		for(int j=0;j<colNum;j++){
    			if(matrix[i][j]=='0') continue;
    			curr=getResult(matrix,i,i,j,j,curr);
    			if(curr>ans) ans=curr;
    		}
    	}
    	return ans;
    }
	
	private int getResult(char[][] matrix, int rowstart, int rowend, int colstart, int colend, int curr) {
		//终止条件:
		if(rowstart<0||colstart<0||rowend>=matrix.length||colend>=matrix[0].length) return -1;
		//如果无法扩展,return
		for(int i=colstart;i<=colend;i++){
			if(matrix[rowstart][i]=='0'||matrix[rowend][i]=='0') return -1;
		}
		for(int i=rowstart;i<=rowend;i++){
			if(matrix[i][colstart]=='0'||matrix[i][colend]=='0') return -1;
		}
		//计算当前矩形面积
		curr=(rowend-rowstart+1)*(colend-colstart+1);
		//当前矩形进行拓展
		int a=getResult(matrix,rowstart-1,rowend,colstart,colend,curr);
		int b=getResult(matrix,rowstart,rowend+1,colstart,colend,curr);
		int c=getResult(matrix,rowstart,rowend,colstart-1,colend,curr);
		int d=getResult(matrix,rowstart,rowend,colstart,colend+1,curr);
		if(a!=-1&&a>=b&&a>=c&&a>=d) return a;
		if(b!=-1&&b>=a&&b>=c&&b>=d) return b;
		if(c!=-1&&c>=a&&c>=b&&c>=d) return c;
		if(d!=-1&&d>=a&&d>=b&&d>=c) return d;
		return curr;
	}

基于最大矩形面积:

	public int maximalRectangle(char[][] matrix) {
		if (matrix == null || matrix.length == 0)
			return 0;
		int[] row = new int[matrix[0].length];// 记录截止到当前行的列高
		int area = 0, currArea = 0;// 记录最大面积和当前最大面积
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix[0].length; j++) {
				if (i == 0)
					row[j] = matrix[i][j] == '1' ? 1 : 0;
				else {
					row[j] = matrix[i][j] == '1' ? row[j] + 1 : 0;
				}
			}
			// 计算截止到当前行的最大矩形
			currArea = getMax(row);
			area = currArea > area ? currArea : area;
		}
		return area;
	}

	private int getMax(int[] height) {
		// 来自:https://leetcode.com/problems/largest-rectangle-in-histogram/discuss/28900/O(n)-stack-based-JAVA-solution
		int len = height.length;
		Stack<Integer> s = new Stack<Integer>();
		int maxArea = 0;
		for (int i = 0; i <= len; i++) {
			int h = (i == len ? 0 : height[i]);
			if (s.isEmpty() || h >= height[s.peek()]) {
				s.push(i);
			} else {
				int tp = s.pop();
				maxArea = Math.max(maxArea, height[tp] * (s.isEmpty() ? i : i - 1 - s.peek()));
				i--;
			}
		}
		return maxArea;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值