Leetcode-85.最大矩形

给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例:

输入:
[
[“1”,”0”,”1”,”0”,”0”],
[“1”,”0”,”1”,”1”,”1”],
[“1”,”1”,”1”,”1”,”1”],
[“1”,”0”,”0”,”1”,”0”]
]
输出: 6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximal-rectangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法1:栈

对每一行统计一次各个列的高度,dp[j]=(matrix[i][j]==’1’)?dp[j+1]:0;

然后对每一行应用84题解法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int n=matrix.size();
if(n==0)
return 0;
int m=matrix[0].size();
int i,j;
int res=0;
vector<int> dp(m,0);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
dp[j]=(matrix[i][j]=='1')?dp[j]+1:0;
}
res=max(res,largestRectangleArea(dp));
}
return res;
}
int largestRectangleArea(vector<int>& heights) {
stack<int> st;
st.push(-1);
int n=heights.size();
int i;
int res=0;
for(i=0;i<n;i++)
{
while(st.top()!=-1&&heights[st.top()]>heights[i])
{
int c=heights[st.top()];
st.pop();
res=max(res,(i-st.top()-1)*c);
}
st.push(i);
}
while(st.top()!=-1)
{
int c=heights[st.top()];
st.pop();
res=max(res,(i-st.top()-1)*c);
}
return res;
}
};

解法2:动态规划

用height记录当前行为底,第j列高度是多少.

用left记录第i行为底,第j列构建最大矩形的左边界(从j列往前左边第一个小于height[j]的位置)

用right记录第j行为底,第j列构建的最大矩形的右边界(从j列往后最右边第一个小于height[i]的位置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int n=matrix.size();
if(n==0)
return 0;
int m=matrix[0].size();
int i,j;
int res=0;
vector<int> height (m,0);
vector<int> left(m,0);
vector<int> right(m,m);
int cur_left=0,cur_right=m;
for(i=0;i<n;i++)
{
cur_left=0;
cur_right=m;
for(j=0;j<m;j++)
height[j]=(matrix[i][j]=='1')?(height[j]+1):0;
for(j=0;j<m;j++)
{
if(matrix[i][j]=='1')
left[j]=max(left[j],cur_left);
else
{
left[j]=0;
cur_left=j+1;
}
}
for(j=m-1;j>=0;j--)
{
if(matrix[i][j]=='1')
right[j]=min(right[j],cur_right);
else
{
right[j]=m;
cur_right=j;
}
}
for(j=0;j<m;j++)
res=max(res,height[j]*(right[j]-left[j]));
}
return res;
}
};