leetcode_085 Maximal Rectangle

题目分析:

  • 给定一个只包含0和1元素的矩阵,求出矩阵中全部包含1的最大矩形面积。

解题思路:

  • 二维动态规划求解

    定义二维数组dp[i][j]用于存放位置(i, j)对应的最大矩形面积。

    1)初始条件:dp[i][col-1] = martix[i][col-1]==’1’)

    2)dp[i][j] = (martix[i][j] == ‘1’) ? 1 + dp[i][j+1] : 0

  • 直方图求解

    对于二维数组中的每一行i,其上面前i行都是一个字符1的连续高度直方图,故可以转换为row个直方图中最大矩形面积。

  • 实现程序

    class Solution
    {
        public:
            int maximalRectangle(vector< vector<char> > &matrix) 
            {
                int row = matrix.size();
                if (row == 0)
                    return 0;
                int column = matrix[0].size();
                int dp[row][column];
                int result = 0;
                // 初始值全部赋值为0 
                for (int i = 0; i < row; i++)
                {
                    for (int j = 0; j < column; j++)
                    {
                        dp[i][j] = 0;
                    }
                }
                // 初始化dp值 
                for (int i = 0; i < row; i++)
                {
                    dp[i][column - 1] = (matrix[i][column - 1] == '1');
                }
                for (int i = 0; i < row; i++)
                {
                    for (int j = column - 2; j >= 0; j--)
                    {
                        if (matrix[i][j] == '1')
                            dp[i][j] = 1 + dp[i][j + 1]; 
                    }
                } 
                //以每个点作为矩形的左上角计算所得的最大矩形面积
                for (int i = 0; i < row; i++)
                {
                    for (int j = 0; j < column; j++)
                    {
                        //剪枝,column-j是最大宽度,row - i是最大高度
                        if ((column - j) * (row - i) <= result)
                            break;
                        int width = dp[i][j];
                        for (int k = i; k < row && width > 0; k++)
                        {
                            //剪枝,row - i是以点(i,j)为左上角的矩形的最大高度
                            if (width * (row - i) <= result)
                                break;
                            if (width > dp[k][j])
                                width = dp[k][j];
                            result = max(result, width * (k - i + 1)); 
                        } 
                    }
                }
                return result; 
            }
            int maximalRectangle1(vector< vector<char> > &matrix)
            {
                if (matrix.size() == 0)
                    return 0;
                int m = matrix.size();
                int n = matrix[0].size();
                vector<int> H(n, 0);
                vector<int> L(n, 0);
                vector<int> R(n, n);
                int result = 0;
                for (int i = 0; i < m; i++)
                {
                    int left = 0;
                    int right = n;
                    //从左到右,累计L(i,j) 
                    for (int j = 0; j < n; j++)
                    {
                        if (matrix[i][j] == '1')
                        {
                            ++H[j];
                            L[j] = max(L[j], left);
                        }
                        else
                        {
                            left = j + 1;
                            H[j] = 0;
                            L[j] = 0;
                            R[j] = n;
                        }
                    } 
                    //从右到左统计R[i,j]
                    for (int j = n -1; j >= 0; j--)
                    {
                        if (matrix[i][j] == '1')
                        {
                            R[j] = min(R[j], right);
                            result = max(result, H[j] * (R[j] - L[j]));
                        }
                        else
                        {
                            right = j;
                        }
                    } 
                }
                return result; 
            }
    };
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值