力扣 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:
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-柱状图最大面积类似,
在每一层求最大柱子面积即可。
在写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;
}
};