Welcome to my blog www.vincentbel.com for viewing.
This is an algorithm problem on Leetcode, the following is my idea of solving this problem and the application of this problem. Topics
Largest rectangular area in a histogram
Given n non-negative integers representing the histogram's bar height where the width of each bar are 1, find the area of L Argest rectangle in the histogram.
Above is a histogram the where width of each bar is 1, given height = [2,1,5,6,2,3].
The largest rectangle is shown in the shaded area, and which has an area = ten unit.
For example,
Given height = [2,1,5,6,2,3],
Return 10.
Simply put: the height of each column of the histogram is known, and the maximum area of the rectangle that can be composed is obtained. Ideas
The maximum rectangular area, whose height must be the height of one of the lowest pillars , for example:
Lowest pillar: Column with a height of 5 (3rd pillar)
Lowest pillar: Column with a height of 4 (4th pillar)
So, the end result must be
max{the largest rectangular area of the lowest pillar with the Pillar I column, 0≤i≤n} max \{the maximum rectangular area of the lowest pillar with the Pillar I, 0 \leq i \leq n \}
So, the question becomes: How to calculate the maximum rectangular area of the column with the Pillar I as the lowest bar. calculate the maximum rectangular area of the lowest column with the Pillar I column Si
The height of Pillar I is height[i];
The maximum rectangular area of the lowest pillar of the pillar I is calculated as SI, the height is known, is height[i]; the bottom length of the base is also calculated:
Starting from Pillar I:
-to the left, the first pillar with a height less than height[i] is counted , and the subscript is left_index;
-to the right, the first pillar with a height less than height[i] is counted , and the subscript is right_index.
The bottom edge length = (right_index-left_index-1), so:
Si = height[i] * (right_index-left_index-1).
For example:
For the 4th pillar (height height[4] = 4), the column to the left of the first height less than height[4] is the 2nd pillar with a height of 2, and the column to the right of the first height less than height[4] is the 6th pillar with a height of 1; so S4 = 4 * (6-2-1) = 12
Traversing all the pillars from left to right, when traversing to the pillar I, if the SI is to be calculated, the left margin is easy to determine, but the right boundary is the pillar to the right of the pillar I, cannot be determined , so the area SI cannot be calculated.
In a different way, the right boundary of the Pillar J (0 < J < i), which is the right boundary of the Pillar I, is determined by traversing to the pillar I, so SJ can calculate it.
Which pillars will be the right boundary of the pillar I. It must be a pillar with a height greater than height[i] .
Using a stack s to store the subscript of a pillar that cannot determine the right boundary, do the following:
-When the stack is empty, I into the stack: S.push (i), i++
-When Height[i] >= the height of the top element of the stack, I into the stack: S.push (i), i++
-When height[i] < the height of the top element of the stack, it is stated that the pillar I is the right boundary of the current stack top element (that is, the s.top () root pillar), so the area can be calculated:
-Right_index = i
-Left_index = The first element at the top of the current stack, just do the following:
-S.pop ();
-Left_index = S.top (); Implement
The specific code is as follows:
int Largestrectanglearea (vector<int> &height) {int n = height.size ();
int i = 0; int max_area = 0;
Maximum area stack<int> s; while (I < n) {if (S.empty () | | height[i] >= height[s.top ()]) {//if stack is empty or height[i] >= stack top element
The height of the I into the stack s.push (i);
i++;
} else {int current = S.top ();//The Subscript s.pop () of the column currently to calculate the area; Left boundary, if the stack is empty, then the first pillar is the left edge//Here The first pillar is labeled 0, so 1 is the left boundary int left_index = S.empty ()?
-1:s.top (); int current_area = height[current] * (i-left_index-1);
Right boundary = = I if (Current_area > Max_area) {//Update maximum area If the current calculated area is larger than all previously calculated areas
Max_area = Current_area;
}}} while (!s.empty ()) {//The area of the remaining elements in the calculation stack int current = S.top ();
S.pop (); int left_index = S.empty ()?
-1:s.top (); int current_area = height[current] * (i-lEFT_INDEX-1);
if (Current_area > Max_area) {max_area = Current_area;
}} return Max_area; }
Simplifying Code
If you give the last element element 0 as the right boundary of all columns, then the stack must be empty after the while (I < n) loop, and the code can be simplified as follows:
int Largestrectanglearea (vector<int> &height) {
height.push_back (0);//finally add an element 0 as the right boundary of all columns
int n = Height.size ();
int i = 0;
int max_area = 0; Maximum area
stack<int> s;
while (I < n) {
if (s.empty () | | height[i] >= height[s.top ()]) {
///If the stack is empty or height[i] >= the height of the top element of the stack, I is pushed into the stack
s.push (i);
i++;
} else {
int current = S.top ();//The Subscript s.pop () of the column currently to calculate the area
;
int left_index = S.empty ()? -1:s.top (); Left bounds
int current_area = height[current] * (i-left_index-1); Right boundary = = I
if (Current_area > Max_area) {
//If the current calculated area is larger than all previously calculated areas, the maximum area is updated
Max_area = current_area;< c22/>}}}
return max_area;
}
Application
Another question on the Leetcode: Maximal Rectangle
Given a 2D binary matrix filled with 0 's and 1 ' s, find the largest rectangle containing all ones and return to its area.
At first, the subject thought it was to calculate the maximum area of the rectangle that contained all 1, so it would be better to take the biggest one. Obviously the topic is not this meaning, the title means that the rectangle is composed of all 1, to seek the maximum area of such a rectangle.
Traversing each row from top to bottom, for line I, as long as the height of each column is calculated (equivalent to the height of each pillar mentioned above), the maximum area can be calculated according to the previous method. calculate the height of each column
Use I to represent the current line, use J for the top, and height[i][j] to indicate its height
-if matrix[i][j] = = ' 0 ', then height[i][j] = 0
-if matrix[i][j] = = ' 1 ':
-If the current is the first row, then height[i][j] = 1
-otherwise: height[i][j] equals the height plus 1 of the front row, which is:
HEIGHT[I][J] = Height[i-1][j] + 1
In fact, only one-dimensional array height[j] is required to represent the height, because when calculating height[j], its value is equal to the height of the front row, namely: height[j] = height[j] + 1. For line 1th, simply initialize Height[j] to 0.
The specific code is as follows:
int Maximalrectangle (vector<vector<char> > &matrix) {int numrows = Matrix.size ();
Number of rows if (numrows <= 0) {return 0; } int numcolumns = Matrix[0].size ();
Number of columns int max_area = 0;
int * height = new Int[numcolumns + 1]; memset (height, 0, NumColumns * sizeof (int)); Initialize height to 0 height[numcolumns] =-1; Finally add element 1 as the right boundary for all elements for (int i = 0; i < numrows; ++i) {//Traverse each line for (int j = 0; J < NumColumns; +
+J) {Height[j] = (matrix[i][j] = = ' 1 ')? Height[j] + 1:0;
} int j = 0;
Stack<int> s; while (J <= NumColumns) {if (S.empty () | | height[j] >= height[s.top ()]) {//If the stack is empty or H
EIGHT[J] >= The height of the top element of the stack, the J-Stack S.push (j);
j + +;
} else {int current = S.top ();//The Subscript s.pop () of the column currently to calculate the area; int left_index = S.empty ()? -1:s.top ();
Left boundary int current_area = height[current] * (j-left_index-1);
Right boundary = = J if (Current_area > Max_area) {//Update maximum area If the current calculated area is larger than all previously calculated areas
Max_area = Current_area;
}}}} delete[] height;
return max_area; }
References
[1] http://www.geeksforgeeks.org/largest-rectangle-under-histogram/