算法练习0115-《85-最大矩形》

力扣 85-最大矩形问题

题目的意思可以理解为一个棋盘上,放了一些棋子,求这些棋子组成的最大面积的矩形面积。

题目如下

Given a rows x cols binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

Example 1:

https://assets.leetcode.com/uploads/2020/09/14/maximal.jpg

Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]

Output: 6

Explanation: The maximal rectangle is shown in the above picture.

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/maximal-rectangle

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:

1. 一个直观方法,构造不同大小的矩形,然后在图中移动,查找是否有符合的,

这个计算量太大。

2. 递归方法,考虑把0的地方剪掉,在剩下的图形中找最大矩形

比如剪掉(1,2)这个位置的0后,可以分别查找剩下的矩形块,找出最大矩形。

这个方法,写起来可能有些复杂。

3. 查找每个棋子作为顶点的矩形面积,需要找宽和高,以高度为例,在找高度的时候,可以采用动态规划的思想来进行优化,h[i] = 1 + h[i+1]

一个固定的顶点可以会有多个矩形,我们可以依次求面积,

这个时候,可以发现,和84-柱状图最大面积类似,

https://assets.leetcode.com/uploads/2021/01/04/histogram.jpg

在每一层求最大柱子面积即可。

在写C++程序的时候需要注意,不能复用vector<vector<char>>& matrix

来存储每个位置的柱子高度,因为char类型是有符号数,最大值为127,217+1 时会溢出,变成负数(-128),


class Solution {

public:

    int maximalRectangle(vector<vector<char>>& matrix) {

        //char '0' is 48

        int h = matrix.size();

        if (h == 0) return 0;

        int w = matrix[0].size();

        if (w == 0) return 0;



        vector<vector<int>> v(h, vector<int>(w+2, 0));

        //set data 

        for (int i = 0; i < 1; i++) {

            for (int j = 0; j < w; j++) {

                v[i][j+1] = matrix[i][j] - '0';

            }

        }

        //set hight

        for (int i = 1; i < h; i++) {

            for (int j = 0; j < w; j++) {

                if (matrix[i][j] == '1') {

                    v[i][j+1] = 1 + v[i-1][j+1];

                }

            }

        }

        //t used as a stack

        int t[202] = {0};

        int p = 0;//pos

        int m = 0;



        for (int i = 0; i < h; i++) {

            p = 0;

            t[p] = 0;

            for (int j = 1; j < w+2; j++) {

                int k = t[p];

        /*        if (v[i][j] > v[i][k]) {

                    p++;

                    t[p] = j;

                } else*/ if (v[i][j] == v[i][k]) {

                    t[p] = j;

                } else {

                    while (v[i][j] < v[i][k]) {

                        int r = j;

                        int l = t[p-1];

                        m = max(m, (r-l-1)*v[i][k]);

                        k = t[--p];

                    }



                    t[++p] = j;                   

                }

            }

        }

        return m;

    }

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值