1.Largest Rectangle in Histogram
Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
For example,
Given heights = [2,1,5,6,2,3],
return 10.
1.思路1:从左至右遍历每一个矩形框的高度,遍历的时候以该高度为中心,知道两边的矩形高度小于中心高度停止,形成一个矩形框。这种方法时间复杂度O(n^2),运行结果会超时。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int max_area=0;
for(int i=0;i<heights.size();i++){
int p=i-1;
int q=i+1;
while(p>=0&&heights[p]>=heights[i])
p--;
while(q<heights.size()&&heights[q]>=heights[i])
q++;
int new_area=(q-p-1)*heights[i];
if(new_area>max_area)
max_area=new_area;
}
return max_area;
}
}
2.思路2:借助栈s,栈中存储数组的下标,如果当前的heights[i]>=heights[s.top()],那么进栈。
否则的话出栈,直到heights[i]>=heights[s.top()]为止,并且每次都记录下s.top()的坐标,index=s.top()。以该坐标为中间点,形成的矩形有left_area和right_area组成。
left_area(包含自身)的宽是:(s.empty()?index+1:index-s.top());
right_area的宽是:i-index-1;
高都是:height[index];
借助栈的进栈出栈之后,时间复杂度可以缩小到O(n).
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int max=0;
stack<int> tmp;
heights.push_back(0);
for(int i=0;i<heights.size();i++){
while(!tmp.empty()&&heights[tmp.top()]>heights[i]){
int index=tmp.top();
tmp.pop();
int left_size=(tmp.empty()?index+1:index-tmp.top())*heights[index];
int right_size=(i-index-1)*heights[index];
if(left_size+right_size>max)
max=left_size+right_size;
}
tmp.push(i);
}
return max;
}
};
2.Maximal Rectangle
Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing only 1’s and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.
解题思路:其实这道题和上面的题是有关系的,把下面的数组
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
映射成:
1 0 1 0 0
1 0 3 2 1
5 4 3 2 1
1 0 0 1 0
显然对于每一列的每一行元素就是上题中矩形的高。
求出每一列的最大矩形之后就可以求出整个矩阵的最大矩形。
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.size()==0)
return 0;
if(matrix[0].size()==0)
return 0;
int row=matrix.size();
int col=matrix[0].size();
int tmp[row+1][col];
memset(tmp,0,sizeof(tmp));
for(int i=0;i<row;i++)
if(matrix[i][col-1]=='1')
tmp[i][col-1]=1;
for(int i=0;i<row;i++)
for(int j=col-2;j>=0;j--)
if(matrix[i][j]=='1')
tmp[i][j]+=1+tmp[i][j+1];
int t[row+1];
int area=0;
int max_area=0;
for(int i=0;i<col;i++){
for(int j=0;j<row+1;j++)
t[j]=tmp[j][i];
area=max_rect(t,row+1);
if(area>max_area)
max_area=area;
}
return max_area;
}
int max_rect(int t[],int length){
stack<int> tmp;
int maxarea=0;
for(int i=0;i<length;i++){
while(!tmp.empty()&&t[tmp.top()]>t[i]){
int index=tmp.top();
tmp.pop();
int left_area=(tmp.empty()?index+1:index-tmp.top())*t[index];
int right_area=(i-index-1)*t[index];
if(left_area+right_area>maxarea)
maxarea=left_area+right_area;
}
tmp.push(i);
}
return maxarea;
}
};