LeetCode·85.最大矩形·单调栈

链接:https://leetcode.cn/problems/maximal-rectangle/solution/by-xun-ge-v-zhxr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

题目

 

示例

 

思路

解题思路
本题与84题思路大体相同,是84题的进阶题,可以移步先看看84题
84.题解
84题是在一维空间求最大矩形,本题是在二维空间求矩形,思路一样,可以将二维空间转换为一维空间与84题一模一样

 

 

暴力求解:
我们按照题目给定要求,枚举数组每一个元素,将对应的高和宽相乘组成面积,保存最大面积即可,因为给定为字符串,所以先对其进行处理,转换为二维整形数组,同时求其在Y方向的高

单调栈+哨兵:
通过暴力解法,时间消耗非常大
那么可以利用递增栈优化暴力暴力求解的过程

  • 当元素大于栈顶元素时,入栈
  • 当元素小于栈顶元素时,维护栈的递增性,将小于当前元素的栈顶元素弹出,并计算面积

在上面递增栈中,我们总是需要判断当前元素是否为最后元素或者为栈顶元素,很麻烦,那么可以在数组前后加上两个哨兵,充当坏点,在实际计算中不影响结果,但是简化我们的逻辑,正如我们高中或者初中学过的辅助线或者凑配法都是差不多的思路

具体实现看代码,注释超级详细

代码

暴力求解:

int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize){
    int dp[matrixSize][matrixColSize[0]];
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i < matrixSize; i++)//计算对应高度
    {
        for(int j = 0; j < matrixColSize[0]; j++)
        {
            if(matrix[i][j] == '1')
            {
                dp[i][j] = (i == 0 ? 0 : dp[i-1][j])+1;
            }
        }
    }
    int max = 0;
    for(int i = 0; i < matrixSize; i++)
    {
        for(int j = 0; j < matrixColSize[0]; j++)//计算每一个点能构成的最大面积
        {
            if(matrix[i][j] == '0')
            {
                continue;
            }
            int min = dp[i][j];//高
            for(int k = j; k >= 0; k--)
            {
                if(matrix[i][k] == '0')
                {
                    break;
                }
                min = fmin(min, dp[i][k]);//每次保存最小高
                max = fmax(max, (j - k + 1) * min);
            }
        }
    }
    return max; 
}

作者:xun-ge-v
链接:https://leetcode.cn/problems/maximal-rectangle/solution/by-xun-ge-v-zhxr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

单调栈+哨兵: 

int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize){
    int dp[matrixSize][matrixColSize[0] + 2];//添加哨兵
    memset(dp, 0, sizeof(dp));//初始化
    for(int i = 0; i < matrixSize; i++)//计算对应高度
    {
        for(int j = 0; j < matrixColSize[0]; j++)
        {
            if(matrix[i][j] == '1')
            {
                dp[i][j+1] = (i == 0 ? 0 : dp[i-1][j+1])+1;
            }
        }
    }
    int max = 0;
    for(int i = 0; i < matrixSize; i++)//转为一维,
    {
        int stack[matrixColSize[0]+2];//单调栈解法
        int top = -1;
        stack[++top] = 0;
        for(int j = 1; j < matrixColSize[0]+2; j++)
        {
                while(dp[i][j] < dp[i][stack[top]])
                {
                    max = fmax(max, (j - stack[top-1] - 1) * dp[i][stack[top]]);
                    --top;
                }
                stack[++top] = j;
        }
    }
    return max;
}


作者:xun-ge-v
链接:https://leetcode.cn/problems/maximal-rectangle/solution/by-xun-ge-v-zhxr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值