题目:
给定一个整形矩阵map,其中的值只有0和1两种,求其中全是1的所有矩阵区域中,最大的矩形的面积。
例如:图中是一个4 × 6的矩形,画出红色的是我们要找到的区域,结果返回为 4.
仔细观察发现:因为我们要找的是矩形,所以它一定是以某个行元素开始的,这样的话,其实我们要找到的某个矩形就转换成以某一个行开始的 histogram的最大矩形问题了。
该问题与histogram的关系与( 连续子序列最大和 和 最大子矩阵和 )情况类似。
public class Solution {
public int maximalRectangle(char[][] matrix) {
if(matrix == null||matrix.length == 0||matrix[0].length == 0)
return 0;
int[][] dp=new int[matrix.length][matrix[0].length];
for(int i=0;i<matrix.length;i++)
{
for(int j=0;j<matrix[0].length;j++)
{
int height=heightFunc(matrix,i,j);
dp[i][j]+=height;
for(int k=j-1;k>=0;k--)
{
if(heightFunc(matrix,i,k) >= height)
{
dp[i][j]+=height;
}else
break;
}
for(int k=j+1;k<matrix[0].length;k++)
{
if(heightFunc(matrix,i,k) >= height)
{
dp[i][j]+=height;
}else
break;
}
}
}
int max=dp[0][0];
for(int i=0;i<dp.length;i++)
{
for(int j=0;j<dp[0].length;j++)
{
if(dp[i][j] > max)
max=dp[i][j];
}
}
return max;
}
public int heightFunc(char[][] matrix,int i,int j)
{
if(matrix[i][j] == '0')
return 0;
int height=0;
while(i>=0&&matrix[i][j] == '1')
{
height++;
i--;
}
return height;
}
}
由于所求的值只与作为子矩形的底边的行有关,可以将dp数组压缩成一维。
import java.util.*;
public class Solution {
public int maximalRectangle(char[][] matrix) {
if(matrix == null||matrix.length == 0||matrix[0].length == 0)
return 0;
int[] dp=new int[matrix[0].length];//压缩为一维数组
int max=0;
for(int i=0;i<matrix.length;i++)
{
Arrays.fill(dp,0);//每次更新底边i时,将dp清空。
for(int j=0;j<matrix[0].length;j++)//简单的一维histogram求法
{
int height=heightFunc(matrix,i,j);
dp[j]+=height;
for(int k=j-1;k>=0;k--)
{
if(heightFunc(matrix,i,k) >= height)
{
dp[j]+=height;
}else
break;
}
for(int k=j+1;k<matrix[0].length;k++)
{
if(heightFunc(matrix,i,k) >= height)
{
dp[j]+=height;
}else
break;
}
if(dp[j] > max)
max=dp[j];
}
}
return max;
}
public int heightFunc(char[][] matrix,int i,int j)//求高度例程
{
if(matrix[i][j] == '0')
return 0;
int height=0;
while(i>=0&&matrix[i][j] == '1')
{
height++;
i--;
}
return height;
}
}