Leetcode个题解85
来源:互联网 发布:淘宝美工面试作品 编辑:程序博客网 时间:2024/06/05 02:57
LEETCODE专题
85. Maximal Rectangle
题目要求:
在一个矩阵中找到所有全为’1’的方形区域的面积并求出最大值。
问题:
- 如何得出这些区域?
- 如何求出这些区域的面积?
分析:
如果大家都被笔者带入去思考第一个问题的话,那么恭喜你,中了本题最大的坑当中了(@_@)。当然对于一些高手来说,这样做也是没有问题的。但是笔者要在这里介绍一下另一种方法,这来自于Leetcode的discussion板块的贡献者morrischen2008大神。
这里要先纠正一下刚刚被笔者带入坑的各位朋友——其实我们根本不用费力去求这些区域,我们只需要记住当前的“最左边界值”、“最右边界值”以及高度即可。这里有关边界值的描述加了引号,是因为这不一定是最左或者最右的,举个例子:[0, 0, 1, 1, 10, 0, 1, 1, 10, 1, 1, 1, 1]
我们从0开始计数。这个时候点(2, 2)的最左边界值就应该为2而非1,如果为1的话高度就会减少。而我们针对这种情况可以采用点[2, 1]最右边界值来参与计算包含该点的矩形,结果为4,即使它不是最大的面积。
有了这一个思路之后,我们就可以来设计这个算法啦。
- 最左边界值的选取。我们可以让每一行每个元素都有这个属性,且这个属性可以继承自上一行的元素的最左边界值。在计算该行最左边界值时,再加入一个参数curLeft,也就是当前未出现0的最左边界值(这里的最左边界值则是真的最左边界值,为了区分,我们用left2表示该值,用left1表示要计算的最左边界值,最右边界值也采用这种方法加以区分),参与计算。在left1和left2之间选取一个最大值作为该点的最左边界值,以保留上一行的高度。
计算顺序:从左到右。 - 最右边界值的选取。除了加入的参数为curRight,且计算的时候选取的是right1与right2的最大值之外,其他的与最左边界值选取过程一致。
计算顺序:从右到左。 - 高度值height选取。高度是一个积累过程,如果有连续的’1’则累加,遇到’0’则清零。
- 面积的计算。有了以上的基础,我们就可以用简单的公式来计算矩形的面积啦。公式就是(right - left) * height。
- 去最大的面积,也就是再将每个面积都比较一下。方法有很多,具体就不再赘述了。
下面直接上代码:
class Solution {public: int max(int a, int b) { return a > b ? a : b; } int min(int a, int b) { return a < b ? a : b; } int maximalRectangle(vector<vector<char>>& matrix) { /* * every item saves its leftest bound, its rightest bound and its height * 1. whenever its char is '0', the cumulative height will be 0 * 2. the rightest bound of each factor is initialed to be the largest value * and calculated from right to left, with the value of minimum of * curRight and the rightest bound of the last row. * 3. the leftest bound of each factor is initialed to be the smallest value * and calculated from left to right, with the value of maximum of * curLeft and the leftest bound of the last row. */ int row = matrix.size(); if (row == 0) return 0; int col = matrix[0].size(); if (col == 0) return 0; int r, c; vector<int> left(col, 0); vector<int> right(col, col); vector<int> height(col, 0); int maxArea = 0; for (r = 0; r < row; r++) { int curLeft = 0; int curRight = col; for (c = 0; c < col; c++) { if (matrix[r][c] == '1') { left[c] = max(left[c], curLeft); height[c]++; } else { left[c] = 0; curLeft = c + 1; height[c] = 0; } } for (c = col - 1; c >= 0; c--) { if (matrix[r][c] == '1') { right[c] = min(right[c], curRight); } else { right[c] = col; curRight = c; } maxArea = max(maxArea, (right[c] - left[c]) * height[c]); } } return maxArea; }};
时间复杂度:O(n)
阅读全文
0 0
- Leetcode个题解85
- leetcode题解
- leetcode题解
- LeetCode 题解
- leetCode题解
- leetcode题解
- leetcode题解
- leetcode题解
- LeetCode题解
- LeetCode题解
- Leetcode题解
- Leetcode题解
- Leetcode题解
- Leetcode题解
- Leetcode题解
- Leetcode题解
- Leetcode题解
- Leetcode题解
- 机器学习实战——AdaBoost
- Python一些基础的东西1
- 微信 js
- 作业系列静态链表
- Maven Unable to compile class for JSP
- Leetcode个题解85
- redis源码分析(1)——简单字符串的实现
- Androidd开发Fragment生命周期中重要几个回调方法
- 消失的draw9patch
- 统计谁没交(简单的C文件操作)
- 监测键盘输入
- Microsoft.NET 企业级应用 架构设计 (上)
- Python爬取当当网亚马逊书名
- 进程间通信(IPC)4 ------ 共享内存(配合使用信号量进行同步)