Largest Rectangle In Histogram

Finding the largest rectangle in histogram.

Histogram

Largest Rectangle in Histogram 1 : 4 * 4 = 16 units.
Largest Rectangle in Histogram 2 : 2 * 6 = 12 units.


The idea behind this algorithm is:
1. For each bar do the following
    a) If the height of the current bar is greater than the height of the previous bar,
       - Store the current bar’s height and the position in their respective stacks.
       Else if the height of the current bar is less than the height of the previous bar
       - Find the area of the largest rectangle that can be formed using the heights and the positions stored in the stack.
       - Pop-out the height and the position of each bar from the stack while calculating the area of the rectangle.
       - Continue finding the area using the heights stored in the stack that are greater than the current bar’s height.
    Push the height of the current bar into the height stack and the position of the previously removed bar.

2. While the height stack is not empty
       - Find the area of the rectangle that can be formed using the histogram size, heights and the positions stored in the stack.
       - Pop-out the height and the position of each bar from the stack while calculating the area of the rectangle.
       - If the calculated area is greater than the earlier calculated areas, the largest rectangle is the newly found rectangle.

Data structure used: Stack(s). One stack is used for storing the height and the other is used for storing the indices of the bars.
Time Complexity: O(n), where n is the number of bars in histograms.


C++14 Finding the largest rectangle in the historgram.

#include<iostream>
#include<stack>
#include<vector>

using namespace std;
typedef vector<int> VI; 
typedef stack<int> SI; 

int GetArea(vector<int> histogram){

    int sz = histogram.size();
    stack<int> stack_of_height, stack_of_position;
    int area=0;
    int index=0,height=1;

    for(int pos=0; pos<sz; pos++){
        // If the height of the current bar is greater than the height 
        // at the top of stack push it.
        if( stack_of_height.empty() || stack_of_height.top() < histogram[pos] ){
            stack_of_height.push(histogram[pos]);
            stack_of_position.push(pos);
        } else {
           if( stack_of_height.top() > histogram[pos] ){
               // If the height of the current bar is less than the height at the top of 
               // the stack, pop out all the bigger heights and their corresponding positions 
               // and find the maximum area.
               while( !stack_of_height.empty() && stack_of_height.top() > histogram[pos] ){
                  index  = stack_of_position.top();
                  stack_of_position.pop();
                  height = stack_of_height.top();
                  stack_of_height.pop();
                  area = max(area, height * (pos-index));
               }
               // Note: We are pushing height of the current bar and the position of the last removed
               // index.
               stack_of_height.push(histogram[pos]);
               stack_of_position.push(index);
           }
        }
    }   

    while(!stack_of_height.empty()){
          int tempArea = stack_of_height.top() * (histogram.size() - stack_of_position.top());
          stack_of_height.pop(); 
          stack_of_position.pop();
          if(tempArea > area){
             area = tempArea;
          }
    }   
    
    return area;
}

int main(){

    vector<int> vec1 = {6, 2, 5, 4, 5, 1, 6}; // 12
    cout << "Histogram {6, 2, 5, 4, 5, 1, 6} : " << GetArea(vec1) << endl;
    vector<int> vec2 = {6}; // 6 
    cout << "Histogram {6} : " << GetArea(vec2) << endl;
    vector<int> vec3 = {7, 2, 1, 4, 5, 1, 3, 3}; // 8
    cout << "Histogram {7, 2, 1, 4, 5, 1, 3, 3} : " << GetArea(vec3) << endl;
    vector<int> vec4 = {4, 1000, 1000, 1000, 1000}; // 4000
    cout << "Histogram {4, 1000, 1000, 1000, 1000} : " << GetArea(vec4) << endl;
    vector<int> vec5 = { 1000, 1000, 1000, 1000}; // 4000
    cout << "Histogram { 1000, 1000, 1000, 1000} : " << GetArea(vec5) << endl;
    vector<int> vec6 = {2, 3, 4, 5, 5, 4, 3, 2}; // 18
    cout << "Histogram {2, 3, 4, 5, 5, 4, 3, 2} : " << GetArea(vec6) << endl;
    vector<int> vec7 = {5, 5, 5, 5, 5}; // 25
    cout << "Histogram {5, 5, 5, 5, 5} : " << GetArea(vec7) << endl;

    return 0;
}

Output

Histogram {6, 2, 5, 4, 5, 1, 6} : 12
Histogram {6} : 6
Histogram {7, 2, 1, 4, 5, 1, 3, 3} : 8
Histogram {4, 1000, 1000, 1000, 1000} : 4000
Histogram { 1000, 1000, 1000, 1000} : 4000
Histogram {2, 3, 4, 5, 5, 4, 3, 2} : 18
Histogram {5, 5, 5, 5, 5} : 25

Copyright © 2019-2020, Algotree.org.
All rights reserved.