85. 最大矩形 - 力扣(LeetCode)
题目:
思路:
单调栈的运用
解法有两种,一种是暴力枚举,一种是单调栈优化
暴力做法很简单,我们同样枚举上界下界,然后枚举列数即可,同时这里我们可以使用一个简单的思路来计算连读h段的长度,可以先去写一下连续0段这题
代码很简单,但是时间复杂度很大,所以不妨考虑优化
我们发现我们题目其实可以变成一个柱形图,什么意思呢?
假设我们枚举到了第 i 行,那么对于每一个 sum[i][j],我们定义为 i 位置往上的最长连读 1 的数量,那么这样一转换就变成了一个柱形图,如

那么这样一直枚举行就相当于每次都求一个矩形图的最大矩形,这样以来我们就优化成了 O(N*M) 的复杂度,大大加快了速率
具体的,我们提前预处理出 sum[i][j],然后暴力枚举 i,对每个 i 都做一个单调栈的操作,同时不要忘了哨兵
参考视频:LeetCode-85 最大矩形 最近太忙啦!水一个视频~_哔哩哔哩_bilibili
代码:
cpp
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int n = matrix.size();
int m = matrix[0].size();
int ans = 0;
for(int i = 0;i < n;i++)
{
vector<int> sum(m,0);
for(int j = i;j < n;j++)
{
int last = -1;
int h = j - i + 1;
for(int z =0;z < m;z++)
{
sum[z] += matrix[j][z] - '0';
if(sum[z] == h) ans = max(ans,h * (z - last));
else last = z;
}
}
}
return ans;
}
};
cpp
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int n = matrix.size();
int m = matrix[0].size();
vector<vector<int>> sum(n,vector<int>(m+2,0));
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
{
if(matrix[i][j] == '0')
continue;
if(i)
sum[i][j+1] = sum[i-1][j+1];
sum[i][j+1]++;
}
}
int ans = 0;
for(int i = 0;i < n;i++)
{
stack<int> st;
for(int j = 0;j < sum[i].size();j++)
{
while(!st.empty() && sum[i][st.top()] > sum[i][j])
{
int h = sum[i][st.top()];
st.pop();
int w = j - st.top() - 1;
ans = max(ans,h*w);
}
st.push(j);
}
}
return ans;
}
};