leetcode 85 Maximal Rectangle 在矩阵中找最大的矩形

本文通过两种方法解析LeetCode第85题——寻找由1组成的最大矩形区域的面积,一种是易于理解但效率较低的方法,另一种则是借鉴第84题思想,实现更高效的解决方案。

如果一上来就拿到这道题可能没有思路,可以看完84题,再看这道题就有思路了。我自己看了别人的博客,讲的我是看的模糊,但是一旦自己做了84题,就简单明了了。我觉得人家讲的也可以:https://www.cnblogs.com/lupx/archive/2015/10/20/leetcode-85.html 看自己咋理解吧

题目:

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

我的笨方法:时间比较慢,但好理解,并不超时:

package test;

public class LC85Try1
{
	public int maximalRectangle(char[][] matrix)
	{
		int ret = 0;//ret是所有的最大面积
		int l=matrix.length;
		if(l==0){
			return ret;
		}
		int m=matrix[0].length;
		for(int i=0;i<l;i++){
			for(int j=0;j<m;j++){
				if(matrix[i][j]=='0'){
					continue;
				}
				int d=1;//深度
				int b=j;//宽度
				
				for(int h=j;h<m;h++){
					if(matrix[i][h]=='0'){						
						break;						
					}
					b=h;
				}
				
				int tmp=d*(b-j+1);//属于【i,j】临时的最大面积
				for(int w=i+1;w<l;w++){
					if(matrix[w][j]=='0'){
						break;
					}
					d++;
					int t=j;
					for(int h=j;h<=b;h++){
						
						if(matrix[w][h]=='0'){
							break;							
						}						
						t=h;
					}	
					b=t;
					if(d*(b-j+1)>tmp){
						tmp=d*(b-j+1);
					}
				}
				if(tmp>ret){
					ret=tmp;
				}
			}
		}
		
		
		return ret;

	}
	public static void main(String[] args)
	{
		LC85Try1 t = new LC85Try1();
		
		char[][] matrix={
				{'1','0','1','0','0'},
				{'1','0','1','1','1'},
				{'1','1','1','1','1'},
				{'1','0','0','1','0'}
		};
		System.out.println(t.maximalRectangle(matrix));
	}

}

利用和84差不多的办法:时间快好多

package test;

import java.util.Arrays;

public class LC85Try2
{
	public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
        
        int m = matrix.length, n = matrix[0].length;
        int[] height = new int[n], left_boundary = new int[n], right_boundary = new int[n];
        int max_area = 0;
        
        Arrays.fill(right_boundary, n);
        
        for (int i = 0; i < m; i++){
            //System.out.println("this is :"+i);
            int cur_left = 0, cur_right = n;//这两个变量用的很巧
            //save the height
            for (int j = 0; j < n; j++){
                if (matrix[i][j] == '1') height[j]++;
                else height[j] = 0;
            }
           /*for(int c1=0;c1<n;c1++){
        	   System.out.print(height[c1]+" , ");
           }
           System.out.println();*/
            
            //search for the left boundary:
            for (int j = 0; j < n; j++){
                if (matrix[i][j] == '1') {
                    left_boundary[j] = Math.max(left_boundary[j], cur_left);
                }else{
                    left_boundary[j] = 0;
                    cur_left = j+1;
                }
            }
            /*for(int c1=0;c1<n;c1++){
         	   System.out.print(left_boundary[c1]+" , ");
            }
            System.out.println();*/
            //search for the right boundary:
            for (int j = n-1; j >= 0; j--){
                if (matrix[i][j] == '1') {
                    right_boundary[j] = Math.min(right_boundary[j], cur_right);
                }else{
                    right_boundary[j] = n;
                    cur_right = j;
                }
            }
            /*for(int c1=0;c1<n;c1++){
          	   System.out.print(right_boundary[c1]+" , ");
             }
             System.out.println();*/
            //search for the max_area
            for (int j = 0; j < n; j++){
                max_area = Math.max(max_area, (right_boundary[j] - left_boundary[j]) * height[j]);
            }
        }
        return max_area;
    }
	public static void main(String[] args)
	{
		LC85Try2 t = new LC85Try2();
		
		char[][] matrix={
				{'1','0','1','0','0'},
				{'1','0','1','1','1'},
				{'1','1','1','1','1'},
				{'1','0','0','1','0'}
		};
		System.out.println(t.maximalRectangle(matrix));
	}

}

下面有个好理解上图的办法:看注释的输出:就知道具体过程,所以我并不理解那个博客:都是dp嘛

this is :0
1 , 0 , 1 , 0 , 0 , 
0 , 0 , 2 , 0 , 0 , 
1 , 5 , 3 , 5 , 5 , 
this is :1
2 , 0 , 2 , 1 , 1 , 
0 , 0 , 2 , 2 , 2 , 
1 , 5 , 3 , 5 , 5 , 
this is :2
3 , 1 , 3 , 2 , 2 , 
0 , 0 , 2 , 2 , 2 , 
1 , 5 , 3 , 5 , 5 , 
this is :3
4 , 0 , 0 , 3 , 0 , 
0 , 0 , 0 , 3 , 0 , 
1 , 5 , 5 , 4 , 5 , 
6

加油,继续


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值