一、题目
给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,
找出只包含 1 的最大矩形,并返回其面积。
示例 1:

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。
示例 2:
输入:matrix = [["0"]]
输出:0
示例 3:
输入:matrix = [["1"]]
输出:1
提示:
rows == matrix.length
cols == matrix[0].length
1 <= rows, cols <= 200
matrix[i][j] 为 '0' 或 '1'
二、思路
做不到,真的做不到...
瞄了眼题解的思路" 数据是1,如果上面第一行也是1,高度就是2,否则是 1;数据是0,则高度直接为0 "。
好思路,接着就是一顿写,修修补补还是不行...
遂研究题解,细看之后发现确实思路很完整:
在之前思路的基础上逐层遍历matrix,每读取完一层后执行一次计算面积的函数。
函数是怎么计算的呢?遍历height,挨个将下标push入单调栈内。如果当前height[i]小于height[栈顶下标](当前高度小于上一个,则结算一次矩形),即计算以他为最矮柱子的最大矩形,然后用栈内下标来计算width。
三、尝试
通过的测试用例:57 / 76 个
cpp
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
vector<vector<int>> dp(matrix.size(),vector<int>(matrix[0].size(),0));
int row=INT_MAX,col=1,ans=0,vert=1,hor=1;
for(int i=0;i<matrix.size();i++){
for(int j=0;j<matrix[0].size();j++){
if(matrix[i][j]=='1'){
ans=max(ans,1);
if(i>=1&&dp[i-1][j]>=1){
dp[i][j]=dp[i-1][j]+1;
ans=max(ans,dp[i][j]);
}
else dp[i][j]=1;
if(j>=1&&dp[i][j-1]!=0){
hor+=1;
ans=max(ans,hor);
}
if(j>=1&&dp[i][j]<=dp[i][j-1]){
col+=1;
row=min(row,dp[i][j]);
ans=max(ans,row*col);
}
else if(j==0) ans=max(ans,dp[i][j]);
else{
col=1;
row=INT_MAX;
hor=1;
}
}
}
col=1;
row=INT_MAX;
hor=1;
}
return ans;
}
};
四、题解
cpp
class Solution {
public:
int maxArea(vector<int>& height){
stack<int> st;
int ans=0;
height.push_back(0); //以防for循环出界
for(int i=0;i<height.size();i++){
while(!st.empty()&&height[st.top()]>height[i]){
int h=height[st.top()]; //当遇到小于栈顶元素的就结算一次
st.pop(); //pop出,维护单调栈
int left=st.empty()?-1:st.top();
int width=i-left-1;
ans=max(ans,width*h);
}
st.push(i);
}
return ans;
}
int maximalRectangle(vector<vector<char>>& matrix) {
vector<int> height(matrix[0].size(),0);
int ans=0;
for(int i=0;i<matrix.size();i++){
for(int j=0;j<matrix[0].size();j++){
if(matrix[i][j]=='1'){
//由于如果中途有0直接归0,一直是1才会累加,所以维护一维的vector即可
height[j]+=1;
}
else height[j]=0;
}
ans=max(ans,maxArea(height));
}
return ans;
}
};