Leetcode:Largest Rectangle in Histogram与Maximal Rectangle

这是非常难理解的两道题,其中第二题要以第一题为基础,否则非常难获得思路。这两题也耗费了大量的时间来研究,消耗了大量脑细胞。

Largest Rectangle in Histogram

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.


Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].


The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given height = [2,1,5,6,2,3],
return 10.

基本思路:要利用到栈。首先把直方图的第一个元素压入栈中。

依次遍历直方图的每一个元素:如果该元素比栈中的栈顶元素大,则压入栈中。如果比栈顶的元素小,则依次弹出栈顶元素,直到此时的栈顶元素比该元素小为止,并且将该元素压入栈中。同时,在出栈的时候,没弹出一个元素,计算此元素能够围成的最大矩形面积,保存在max中。

采用这种方法,遍历完所有元素之后,max的值则为需要所求最大矩形面积。

public class Solution {
    public int largestRectangleArea(int[] height) {
        if (height == null || height.length == 0) {
            return 0;
        }
        
        Stack<Integer> stack = new Stack<Integer>();
        int max = 0;
        for (int i = 0; i <= height.length; i++) {
            int curt = (i == height.length) ? -1 : height[i];
            while (!stack.isEmpty() && curt <= height[stack.peek()]) {
                int h = height[stack.pop()];
                int w = stack.isEmpty() ? i : i - stack.peek() - 1;
                max = Math.max(max, h * w);
            }
            stack.push(i);
        }
        
        return max;
    }
}

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”的最大子矩阵面积。解题思路:根据行遍历此矩阵,把每一行当作是一个直方图。这里又涉及到了矩阵和直方图的转化问题。

首先对于每一列,如果元素对应的上一行元素也为1,则该元素对应直方图高度为1+1,如果上一行的上一行依然为1,则对应高度为1+1+1,以此类推。这样即实现了矩阵每一行对应于一个直方图。

例如:



最后即可遍历矩阵中的每一行,按照上题求直方图最大子矩阵面积的方法,完成此题。

public class Solution {
public int maximalRectangle(char[][] matrix) {
    if (matrix==null||matrix.length==0)
        return 0;
    if (matrix[0]==null||matrix[0].length==0)
        return 0;

    int[] record = new int[matrix[0].length];
    Arrays.fill(record,0);
    int result = 0;

    Stack<Integer> index = new Stack<Integer>();
    index.push(-1);

    for (int i=0;i<matrix.length;i++){
        for (int j=0;j<matrix[0].length;j++){
            if (matrix[i][j]=='1')
                record[j]+=1;
            else
                record[j]=0;

            while(index.peek()>-1)
                if (record[index.peek()]>record[j]){
                    int top=index.pop();
                    result=Math.max(result,record[top]*(j-index.peek()-1));
                }
                else break;

            index.push(j);
        }
        while(index.peek()>-1){

            int top=index.pop();
            if (record[top]>0)
                result=Math.max(result,record[top]*(matrix[0].length-index.peek()-1));
        }
    }
    return result;    
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值