Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
思路:本题给你包含0和1的矩阵,让你找出包含1的最大矩阵,并返回其面积。这道题可以枚举出所有矩阵求出其中的最大面积,如果枚举出高度和宽度,时间复杂度要到O(n^4)了,那么我们可以这样从矩阵的左上角的位置开始,这样计算以某一点为左上角的矩阵的最大面积。
1.高度为1时,宽度为第一行中从第一个位置起连续的1的个数,这样求出其面积
2.高度为2时,宽度为第二行中从第一个位置其连续的1的个数,宽度为其最小值,这样求出面积
3.一次类推,宽度为和上一行宽度的最小值。
我们可以使用动态规划方程来计算每一行的连续1的个数,我们从每一行的尾部算起。
初始状态:dp[i][col-1]=(matrix[i][col-1]=='1);dp[i][j]=((matrix[i][j]=='1')?1+dp[i][j]:0)
最后,就是在三层for循环下,找出最大面积。
class Solution { public: int maximalRectangle(vector<vector<char> > &matrix) { int row=matrix.size(); if(row==0) return 0; int col=matrix[0].size(); int dp[row][col]; int result=0; memset(dp,0,sizeof(dp)); for(int i=0;i<row;i++) { dp[i][col-1]=(matrix[i][col-1]=='1'); } for(int i=0;i<row;i++) { for(int j=col-2;j>=0;j--) { if(matrix[i][j]=='1') { dp[i][j]=1+dp[i][j+1]; } else dp[i][j]=0; } } for(int i=0;i<row;i++) { for(int j=0;j<col;j++) { if((row-i)*(col-j)<=result)//这里可以优化,直接跳过小于等于result的情况 break; int width=dp[i][j]; for(int k=i;k<row&&width>0;k++) { if(width*(row-i)<=result)//这里可以优化,直接跳过小于等于result的情况 break; width=min(width,dp[k][j]); result=max(result,width*(k-i+1)); } } } return result; } };
思路二:时间复杂度为O(n^2).借用Largest Rectangle in Histogram思想,将此题包含连续1的个数转化为直方图。
class Solution { public: int MaxRectangle(vector<int> &height) { int len=height.size(); if(len==0) return 0; stack<int> s; height.push_back(0); int maxArea=0; int area=0; for(int i=0;i<=len;) { if(s.empty()||height[s.top()]<=height[i]) { s.push(i); i++; } else { int k=s.top(); s.pop(); if(s.empty()) area=height[k]*i; else area=height[k]*(i-s.top()-1); maxArea=max(maxArea,area); } } return maxArea; } int maximalRectangle(vector<vector<char> > &matrix) { int row=matrix.size(); if(row==0) return 0; int col=matrix[0].size(); vector<vector<int> > height(row,vector<int>(col,0)); for(int i=0;i<row;i++) { for(int j=0;j<col;j++) { if(i==0) { height[i][j]=(matrix[i][j]=='1'); } else { height[i][j]=((matrix[i][j]=='1')?1+height[i-1][j]:0); } } } int result=0; int area; for(int i=0;i<row;i++) { area=MaxRectangle(height[i]); result=max(result,area); } return result; } };