LeetCode——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.

» Solve this problem


题目要求的是由1组成的最大的矩形。

附上一个图能更好地说明题意:

100011
111011
111100
101111
111111
左上角编号(0, 0),右下角编号(4, 5)

全部由1组成的矩形有:

面积为1,23个(可能数错了,欢迎大家指正);

面积为2,29个;

面积为3,15个;

面积为4,15个;

面积为5,3个;

面积为6,4个;

面积为8,1个( (3,2) -> (4, 5) )

最大的矩形面积为8。


其实这题稍加转换后就是Largest Rectangle in Histogram

先看第一行,1 0 0 0 1 1,Largest Rectangle in Histogram为2。

再看第一行+第二行, 1 0 0 0 1 1

                                        1 1 1 0 1 1,转化为Histogram,就是2 1 1 0 2 2,Largest Rectangle in Histogram为4。

所以,我的思路就是遍历所有行,当遍历第i行时,将1~i转化为Histogram,求出Largest Rectangle。


class Solution {
public:
    int maximalRectangle(vector<vector<char> > &matrix) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int m = matrix.size();
        if (m == 0) {
            return 0;
        }
        int n = matrix[0].size();
        if (n == 0) {
            return 0;
        }
        
        int max = 0;
        int height[n], l[n], r[n];
        memset(height, 0, sizeof(int) * n);
        
        for (int i = 0; i < m; i++) {
            memset(l, 0, sizeof(int) * n);
            memset(r, 0, sizeof(int) * n);
            
            for (int j = 0; j < n; j++) {
                if (i == 0) {
                    height[j] = matrix[i][j] == '0' ? 0 : 1;
                }
                else {
                    height[j] = matrix[i][j] == '0' ? 0 : height[j] + 1;
                }
            }
            
            for (int j = 0; j < n; j++) {
                if (j == 0 || height[j - 1] < height[j]) {
                    l[j] = j;
                }
                else {
                    int idx = l[j - 1];
                    while (idx > 0 && height[j] <= height[idx - 1]) {
                        idx = l[idx - 1];
                    }
                    l[j] = idx;
                }
            }
            
            for (int j = n - 1; j >= 0; j--) {
                if (j == n - 1 || height[j + 1] < height[j]) {
                    r[j] = j;
                }
                else {
                    int idx = r[j + 1];
                    while (idx < n - 1 && height[j] <= height[idx + 1]) {
                        idx = r[idx + 1];
                    }
                    r[j] = idx;
                }
            }
            
            for (int j = 0; j < n; j++) {
                if ((r[j] - l[j] + 1) * height[j] > max) {
                    max = (r[j] - l[j] + 1) * height[j];
                }
            }
        }
        
        return max;
    }
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值