题目如下:
给你一个二维矩阵,权值为False
和True
,找到一个最大的矩形,使得里面的值全部为True
,输出它的面积。
样例
给你一个矩阵如下
[
[1, 1, 0, 0, 1],
[0, 1, 0, 0, 1],
[0, 0, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 1]
]
输出6
没接触过这类型的题目一开始可能不知所措。遍历方法不外乎一个个遍历了,这类棋牌型的题目也没什么特别好的遍历方法。但是,我们可以针对一特殊整体来求解。这思路重点就是把连续元素个数映射到某一行上,让其独立并求解。
从上面的矩阵可以看成下面这样
然而,我们可以把每一行的连续元素都标志上表示在该行上面有多少个连续元素。
到目前为止,我们将在某行上连续的元素个数映射到该行上,我们也就可以对其做独立的面积求解了。此时只需要用短板横切的方式即可求的所在行的最大矩形。
思路代码实现如下:
#define max(a,b) (a)>(b)?(a):(b)
void Method(vector<vector<bool>> &v)
{
int h=v.size(),w=v[0].size(),i,j,l,r,u,m=0;
int *t=new int[w+1];
stack<int> s;
memset(t,0,4*(w+1));
for(i=0; i<h; ++i)
{
while(!s.empty())s.pop();
for(j=0; j<=w; ++j)
{
t[j]=v[i][j]==0?0:t[j]+1;
}
for(j=0; j<=w; ++j)
{
while(!s.empty()&&t[s.top()]>t[j])
{
u=s.top(),s.pop();
l=(s.empty()?u+1:u-s.top())*t[u];
r=(j-u-1)*t[u];
m=max(l+r,m);
}
s.push(j);
}
}
delete[] t;
printf("%d",m);
}