题目:
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
思路:
基本思路是循环确定一个左上角的点与右下角的点,然后判断该区域是否都为’1‘。如下图:
为了循环利用,我们可以采用动态规划的思路:
1)当左上角与右下角的点相同时,判断该位置是否为’1‘
2)当左上角与右下角不同时,我们可以循环利用之前的结果,即若下述三个图的方形区域满足全为’1‘时,当前区域全为1。
思路1:产生一个思维矩阵来存储结果。rectangle[i][j][k][l]表示从左上角点(i,j)到右下角点(k,l)中的矩形区域是否全为’1‘。显然空间复杂度O(n4)不是很理想。
思路2:在思路1的基础上优化空间复杂度。循环时每次选定一个左上角的点,采用一个二位矩阵来表示左上角的点到任意一个右下角的矩形区域是否全为’1‘。每次循环时,O(n2)的空间被复写。
代码:
思路1:
class Solution {
public:
bool**** rectangle;
int maximalRectangle(vector<vector<char> > &matrix) {
int n = matrix.size();
rectangle = new bool***[n];
int max=0;
for(int i=0;i<n;i++)
{
rectangle[i] = new bool**[n];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
rectangle[i][j] = new bool*[n];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
{
rectangle[i][j][k] = new bool[n];
max = 1;
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
for(int k=i;k<n;k++)
{
for(int l=l;l<n;l++)
{
if(i==k&&j==l)
{
continue;
}
else if(i==k)
{
rectangle[i][j][k][l] = rectangle[i][j][k][l-1] + rectangle[k][l][k][l];
if(rectangle[i][j][k][l])
{
int area = l-j+1;
if(area > max)
max = area;
}
}
else if(j==l)
{
rectangle[i][j][k][l] = rectangle[i][j][k-1][l] + rectangle[k][l][k][l];
if(rectangle[i][j][k][l])
{
int area = k-i+1;
if(area > max)
max = area;
}
}
else
{
rectangle[i][j][k][l] = rectangle[i][j][k-1][l] + rectangle[i][j][k][l-1] + rectangle[k][l][k][l];
if(rectangle[i][j][k][l])
{
int area = (k-i+1)*(l-j+1);
if(area > max)
max = area;
}
}
}
}
}
}
return max;
}
};
思路2:
class Solution {
public:
bool** rectangle;
int maximalRectangle(vector<vector<char> > &matrix) {
if(matrix.size()==0||matrix[0].size()==0)
return 0;
int n = matrix.size();
int m = matrix[0].size();
rectangle = new bool*[n];
int max=0;
for(int i=0;i<n;i++)
{
rectangle[i] = new bool[m];
}
for(int k=0;k<n;k++)
{
for(int l=0;l<m;l++)
{
rectangle[k][l]=(matrix[k][l]=='1');
for(int i=k;i<n;i++)
{
bool end = false;
for(int j=l;j<m;j++)
{
if(i==k&&j==l)
{
if(rectangle[i][j])
{
int area = 1;
if(area > max)
max = area;
}
else
{
end = true;
break;
}
}
else if(i==k)
{
rectangle[i][j] = rectangle[i][j-1] && (matrix[i][j]=='1');
}
else if(j==l)
{
rectangle[i][j] = rectangle[i-1][j] && (matrix[i][j]=='1');
}
else
{
rectangle[i][j] = rectangle[i][j-1] && rectangle[i-1][j] && (matrix[i][j]=='1');
}
if(rectangle[i][j])
{
int area = (i-k+1)*(j-l+1);
if(area > max)
max = area;
}
else
{
break;
}
}
if(end)
{
break;
}
}
}
}
return max;
}
};