Maximal Rectangle
来源:互联网 发布:淘宝聚划算是正品吗 编辑:程序博客网 时间:2024/05/17 13:09
一. Maximal Rectangle
Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing only 1’s and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.
Difficulty:Hard
TIME:42MIN
解法一(动态规划)
虽然一开始也想到了动态规划的解法,但是最优子结构设计上有一些问题,导致算法的时间复杂度为
这里采用的最优子结构使用三个数组,分别是height,left和right数组,记录每一行某个点所在的最大的长方形的高度,左边界和右边界。这个最优子结构难以理解的地方就是怎样才能保证该点记录的一定是最大的长方形的高度,左边界和右边界。
对于某个矩阵来说,比如:
/*0 0 1 0 00 1 1 1 01 1 1 1 1第一行 0 0 1 0 0h 0 0 1 0 0l 0 0 2 0 0r 5 5 3 5 5第二行 0 1 1 1 0h 0 1 2 1 0l 0 1 2 1 0r 5 4 3 4 5第三行 略*/
可以发现,每个点记录的确实是该点所在可能的最大的矩阵的高度,左边界和右边界。注意这里记录的是可能,比如对于第二行来说,记录的第二个1的矩阵面积为2,显然不是最大的,不过,这一点也至关重要,就是矩阵的记录一定是高度优先的,也就是我只记录以该点所在的最大高度的矩阵,而我并不关心这个矩阵是否是最大的矩阵。
因为次高的矩阵一定会有其他点来记录,比如第二行的第一个1和第三个1记录的就是次高的矩阵。因此,就算每个点都记录该点的最高的矩阵,但是我们还是会记录出所有的可能的最大的矩阵,而不会漏掉任何一种情况。
这个就是这种解法最精妙的地方。
int maximalRectangle(vector<vector<char>>& matrix) { if(matrix.empty() || matrix[0].empty()) return 0; int result = 0; vector<int> height(matrix[0].size(), 0); vector<int> left(matrix[0].size(), 0); vector<int> right(matrix[0].size(), matrix[0].size()); for(int i = 0; i < matrix.size(); i++) { int curLeft = 0, curRight = matrix[0].size(); for(int j = 0; j < matrix[0].size(); j++) { if(matrix[i][j] == '1') { height[j]++; left[j] = max(left[j], curLeft); //记录最高的矩阵的左边界 } else { height[j] = 0; left[j] = 0; curLeft = j + 1; } } for(int j = matrix[0].size() - 1; j >= 0; j--) { if(matrix[i][j] == '1') right[j] = min(right[j], curRight); //记录最高的矩阵的右边界 else { right[j] = matrix[0].size(); curRight = j; } result = max(result,(right[j]-left[j]) * height[j]); } } return result;}
代码的时间复杂度为
解法二(栈)
之前做过一道题Largest Rectangle in Histogram,一开始确实没有联想到这两道题的相关性,不过,直方图既然可以在
int maximalRectangle(vector<vector<char>>& matrix) { if(matrix.empty() || matrix[0].empty()) return 0; int result = 0; vector<int> v(matrix[0].size() + 1, 0); for(int i = 0; i < matrix.size(); i++) { vector<int> s; for(int j = 0; j <= matrix[0].size(); j++) { if(j < matrix[0].size() && matrix[i][j] == '1') v[j]++; else v[j] = 0; while(!s.empty() && v[j] < v[s.back()]) { int h = v[s.back()]; s.pop_back(); int k = s.empty() ? -1 : s.back(); result = max((j - k - 1) * h, result); } s.push_back(j); } } return result;}
代码的时间复杂度为
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- Maximal Rectangle
- 将图片转换成字符串
- Android6.0动态权限整理
- sql中join语句中条件在on与where区别
- DataBinding eventbus butterknife 使用apt的冲突
- 自定义控件之圆盘形控制按钮WheelView
- Maximal Rectangle
- Android Studio 2.3后,找不到Launch Standalone SDK Manager
- Window下用eclipse开发c
- 话说有关precision 5520(大电池版无机械硬盘,仅一个nvme硬盘)上作ubuntu系统的教程step by step
- 使用CSDN-markdown编辑器
- 字符串作为函数模版实参的特殊情况
- 由于外键约束无法删除数据
- 笔试面试题汇总---4月
- c++转C#