Given a histogram represented by an array arr[], where each element of the array denotes the height of the bars in the histogram. All bars have the same width of 1 unit.
Task is to find the largest rectangular area possible in a given histogram where the largest rectangle can be made of a number of contiguous bars whose heights are given in an array.
Explanation: We get the maximum are by picking bars highlighted above in green (50, and 60). The area is computed (smallest height) * (no. of the picked bars) = 50 * 2 = 100.
Input: arr[] = [3, 5, 1, 7, 5, 9] Output: 15 Explanation: We get the maximum are by picking bars 7, 5 and 9. The area is computed (smallest height) * (no. of the picked bars) = 5 * 3 = 15.
[Naive Approach] By Finding Max Area of Rectangles all Heights - O(n^2) Time and O(1) Space
The idea is to consider each bar as the minimum height and find the maximum area. We traverse toward left of it and add its height until we see a smaller element. We do the same thing for right side of it.
So the area with current bar as minimum is going to be height of current bar multiplied by total width traversed on both left and right including the current bar. The area is the bar’s height multiplied by the total traversed width. Finally, we return the maximum of all such areas.
C++
// C++ program to find the largest rectangular area possible // in a given histogram #include<bits/stdc++.h>usingnamespacestd;// Function to calculate the maximum rectangular// area in the HistogramintgetMaxArea(vector<int>&arr){intres=0,n=arr.size();// Consider every bar one by onefor(inti=0;i<n;i++){intcurr=arr[i];// Traverse left while we have a greater height barfor(intj=i-1;j>=0&&arr[j]>=arr[i];j--)curr+=arr[i];// Traverse right while we have a greater height bar for(intj=i+1;j<n&&arr[j]>=arr[i];j++)curr+=arr[i];res=max(res,curr);}returnres;}intmain(){vector<int>arr={60,20,50,40,10,50,60};cout<<getMaxArea(arr);return0;}
C
// Cprogram to find the largest rectangular area possible // in a given histogram #include<stdio.h>// Function to calculate the maximum rectangular// area in the HistogramintgetMaxArea(intarr[],intn){intres=0;// Consider every bar one by onefor(inti=0;i<n;i++){intcurr=arr[i];// Traverse left while we have a greater height barfor(intj=i-1;j>=0&&arr[j]>=arr[i];j--){curr+=arr[i];}// Traverse right while we have a greater height barfor(intj=i+1;j<n&&arr[j]>=arr[i];j++){curr+=arr[i];}if(curr>res){res=curr;}}returnres;}intmain(){intarr[]={60,20,50,40,10,50,60};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",getMaxArea(arr,n));return0;}
Java
// Java program to find the largest rectangular area possible // in a given histogram importjava.util.*;classGfG{// Function to calculate the maximum rectangular// area in the HistogramstaticintgetMaxArea(int[]arr){intres=0,n=arr.length;for(inti=0;i<n;i++){intcurr=arr[i];// Traverse left while we have a greater height barfor(intj=i-1;j>=0&&arr[j]>=arr[i];j--)curr+=arr[i];// Traverse right while we have a greater height barfor(intj=i+1;j<n&&arr[j]>=arr[i];j++)curr+=arr[i];res=Math.max(res,curr);}returnres;}publicstaticvoidmain(String[]args){int[]arr={60,20,50,40,10,50,60};System.out.println(getMaxArea(arr));}}
Python
# Python program to find the largest rectangular area possible # in a given histogram # Function to calculate the maximum rectangular# area in the HistogramdefgetMaxArea(arr):res=0n=len(arr)foriinrange(n):curr=arr[i]# Traverse left while we have a greater height barj=i-1whilej>=0andarr[j]>=arr[i]:curr+=arr[i]j-=1# Traverse right while we have a greater height barj=i+1whilej<nandarr[j]>=arr[i]:curr+=arr[i]j+=1res=max(res,curr)returnresif__name__=="__main__":arr=[60,20,50,40,10,50,60]print(getMaxArea(arr))
C#
// C# program to find the largest rectangular area possible // in a given histogram usingSystem;classGfG{// Function to calculate the maximum rectangular// area in the HistogramstaticintgetMaxArea(int[]arr){intn=arr.Length;intres=0;// Consider every bar one by onefor(inti=0;i<n;i++){intcurr=arr[i];// Traverse left while we have a greater height barintj=i-1;while(j>=0&&arr[j]>=arr[i]){curr+=arr[i];j--;}// Traverse right while we have a greater height barj=i+1;while(j<n&&arr[j]>=arr[i]){curr+=arr[i];j++;}res=Math.Max(res,curr);}returnres;}staticvoidMain(string[]args){int[]arr={60,20,50,40,10,50,60};Console.WriteLine(getMaxArea(arr));}}
JavaScript
// JavaScript program to find the largest rectangular area possible // in a given histogram // Function to calculate the maximum rectangular// area in the HistogramfunctiongetMaxArea(arr){letn=arr.length;letres=0;// Consider every bar one by onefor(leti=0;i<n;i++){letcurr=arr[i];// Traverse left while we have a greater height barletj=i-1;while(j>=0&&arr[j]>=arr[i]){curr+=arr[i];j--;}// Traverse right while we have a greater height barj=i+1;while(j<n&&arr[j]>=arr[i]){curr+=arr[i];j++;}res=Math.max(res,curr);}returnres;}// Driver codeletarr=[60,20,50,40,10,50,60];console.log(getMaxArea(arr));
Output
100
[Expected Approach] Precomputing (Using Two Stack) - O(n) Time and O(n) Space
The idea is based on the naive approach. Instead of linearly finding previous smaller and next smaller for every element, we find previous smaller and next smaller for the whole array in linear time.
Build an array prevS[] in O(n) time using stack that holds index of previous smaller element for every item.
Build another array nextS[] in O(n) time using stack that holds index of next smaller element for every item.
Now do following for every element arr[i]. Consider arr[i] find width of the largest histogram with arr[i] being the smallest height. width = nextS[i] - prevS[i] - 1. Now find the area as arr[i] * width.
Return the maximum of all values found in step 3.
C++
// C++ program to find the largest rectangular area possible // in a given histogram #include<bits/stdc++.h>usingnamespacestd;// Function to find next smaller for every elementvector<int>nextSmaller(vector<int>&arr){intn=arr.size();// Initialize with n for the cases when next smaller// does not existvector<int>nextS(n,n);stack<int>st;// Traverse all array elements from left to rightfor(inti=0;i<n;++i){while(!st.empty()&&arr[i]<arr[st.top()]){// Setting the index of the next smaller element// for the top of the stacknextS[st.top()]=i;st.pop();}st.push(i);}returnnextS;}// Function to find previous smaller for every elementvector<int>prevSmaller(vector<int>&arr){intn=arr.size();// Initialize with -1 for the cases when prev smaller// does not existvector<int>prevS(n,-1);stack<int>st;// Traverse all array elements from left to rightfor(inti=0;i<n;++i){while(!st.empty()&&arr[i]<arr[st.top()]){// Setting the index of the previous smaller element// for the top of the stackst.pop();}if(!st.empty()){prevS[i]=st.top();}st.push(i);}returnprevS;}// Function to calculate the maximum rectangular// area in the HistogramintgetMaxArea(vector<int>&arr){vector<int>prevS=prevSmaller(arr);vector<int>nextS=nextSmaller(arr);intmaxArea=0;// Calculate the area for each Histogram barfor(inti=0;i<arr.size();++i){intwidth=nextS[i]-prevS[i]-1;intarea=arr[i]*width;maxArea=max(maxArea,area);}returnmaxArea;}intmain(){vector<int>arr={60,20,50,40,10,50,60};cout<<getMaxArea(arr)<<endl;return0;}
C
// C program to find the largest rectangular area possible // in a given histogram #include<stdio.h>#include<stdlib.h>// Stack structurestructStack{inttop;intcapacity;int*items;};// Function to create an empty stack with dynamic memory allocationstructStack*createStack(intcapacity){structStack*stack=(structStack*)malloc(sizeof(structStack));stack->capacity=capacity;stack->top=-1;stack->items=(int*)malloc(stack->capacity*sizeof(int));returnstack;}// Function to check if the stack is emptyintisEmpty(structStack*stack){returnstack->top==-1;}// Function to push an element onto the stackvoidpush(structStack*stack,intvalue){if(stack->top==stack->capacity-1){printf("Stack overflow\n");return;}stack->items[++(stack->top)]=value;}// Function to pop an element from the stackintpop(structStack*stack){if(isEmpty(stack)){printf("Stack underflow\n");return-1;}returnstack->items[(stack->top)--];}// Function to get the top element of the stackintpeek(structStack*stack){if(!isEmpty(stack)){returnstack->items[stack->top];}return-1;}// Function to find the next smaller element for every elementvoidnextSmaller(intarr[],intn,intnextS[]){structStack*stack=createStack(n);// Initialize with n for the cases// when next smaller does not existfor(inti=0;i<n;i++){nextS[i]=n;}// Traverse all array elements from left to rightfor(inti=0;i<n;i++){while(!isEmpty(stack)&&arr[i]<arr[peek(stack)]){nextS[peek(stack)]=i;pop(stack);}push(stack,i);}}// Function to find the previous smaller element for every elementvoidprevSmaller(intarr[],intn,intprevS[]){structStack*stack=createStack(n);// Initialize with -1 for the cases when prev smaller does not existfor(inti=0;i<n;i++){prevS[i]=-1;}// Traverse all array elements from left to rightfor(inti=0;i<n;i++){while(!isEmpty(stack)&&arr[i]<arr[peek(stack)]){pop(stack);}if(!isEmpty(stack)){prevS[i]=peek(stack);}push(stack,i);}}// Function to calculate the maximum rectangular// area in the HistogramintgetMaxArea(intarr[],intn){int*prevS=(int*)malloc(n*sizeof(int));int*nextS=(int*)malloc(n*sizeof(int));intmaxArea=0;// Find previous and next smaller elementsprevSmaller(arr,n,prevS);nextSmaller(arr,n,nextS);// Calculate the area for each arrogram barfor(inti=0;i<n;i++){intwidth=nextS[i]-prevS[i]-1;intarea=arr[i]*width;if(area>maxArea){maxArea=area;}}returnmaxArea;}// Driver codeintmain(){intarr[]={60,20,50,40,10,50,60};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",getMaxArea(arr,n));return0;}
Java
// Java program to find the largest rectangular area possible // in a given histogram importjava.util.Stack;classGfG{// Function to find next smaller for every elementstaticint[]nextSmaller(int[]arr){intn=arr.length;// Initialize with n for the cases when next smaller// does not existint[]nextS=newint[n];for(inti=0;i<n;i++){nextS[i]=n;}Stack<Integer>st=newStack<>();// Traverse all array elements from left to rightfor(inti=0;i<n;i++){while(!st.isEmpty()&&arr[i]<arr[st.peek()]){// Setting the index of the next smaller element// for the top of the stacknextS[st.pop()]=i;}st.push(i);}returnnextS;}// Function to find previous smaller for every elementstaticint[]prevSmaller(int[]arr){intn=arr.length;// Initialize with -1 for the cases when prev smaller// does not existint[]prevS=newint[n];for(inti=0;i<n;i++){prevS[i]=-1;}Stack<Integer>st=newStack<>();// Traverse all array elements from left to rightfor(inti=0;i<n;i++){while(!st.isEmpty()&&arr[i]<arr[st.peek()]){st.pop();}if(!st.isEmpty()){prevS[i]=st.peek();}st.push(i);}returnprevS;}// Function to calculate the maximum rectangular// area in the histogramstaticintgetMaxArea(int[]arr){int[]prevS=prevSmaller(arr);int[]nextS=nextSmaller(arr);intmaxArea=0;// Calculate the area for each arrogram barfor(inti=0;i<arr.length;i++){intwidth=nextS[i]-prevS[i]-1;intarea=arr[i]*width;maxArea=Math.max(maxArea,area);}returnmaxArea;}publicstaticvoidmain(String[]args){int[]arr={60,20,50,40,10,50,60};System.out.println(getMaxArea(arr));}}
Python
# Python program to find the largest rectangular area possible # in a given histogram # Function to find next smaller for every elementdefnextSmaller(arr):n=len(arr)# Initialize with n for the cases when next smaller# does not existnextS=[n]*nst=[]# Traverse all array elements from left to rightforiinrange(n):whilestandarr[i]<arr[st[-1]]:# Setting the index of the next smaller element# for the top of the stacknextS[st.pop()]=ist.append(i)returnnextS# Function to find previous smaller for every elementdefprevSmaller(arr):n=len(arr)# Initialize with -1 for the cases when prev smaller# does not existprevS=[-1]*nst=[]# Traverse all array elements from left to rightforiinrange(n):whilestandarr[i]<arr[st[-1]]:st.pop()ifst:prevS[i]=st[-1]st.append(i)returnprevS# Function to calculate the maximum rectangular# area in the HistogramdefgetMaxArea(arr):prevS=prevSmaller(arr)nextS=nextSmaller(arr)maxArea=0# Calculate the area for each arrogram barforiinrange(len(arr)):width=nextS[i]-prevS[i]-1area=arr[i]*widthmaxArea=max(maxArea,area)returnmaxAreaif__name__=="__main__":arr=[60,20,50,40,10,50,60]print(getMaxArea(arr))
C#
// C# program to find the largest rectangular area possible // in a given histogram usingSystem;usingSystem.Collections.Generic;classGfG{// Function to find next smaller for every elementstaticint[]nextSmaller(int[]arr){intn=arr.Length;// Initialize with n for the cases when next smaller// does not existint[]nextS=newint[n];for(inti=0;i<n;i++){nextS[i]=n;}Stack<int>st=newStack<int>();// Traverse all array elements from left to rightfor(inti=0;i<n;i++){while(st.Count>0&&arr[i]<arr[st.Peek()]){// Setting the index of the next smaller element// for the top of the stacknextS[st.Pop()]=i;}st.Push(i);}returnnextS;}// Function to find previous smaller for every elementstaticint[]prevSmaller(int[]arr){intn=arr.Length;// Initialize with -1 for the cases when prev smaller// does not existint[]prevS=newint[n];for(inti=0;i<n;i++){prevS[i]=-1;}Stack<int>st=newStack<int>();// Traverse all array elements from left to rightfor(inti=0;i<n;i++){while(st.Count>0&&arr[i]<arr[st.Peek()]){st.Pop();}if(st.Count>0){prevS[i]=st.Peek();}st.Push(i);}returnprevS;}// Function to calculate the maximum rectangular// area in the HistogramstaticintgetMaxArea(int[]arr){int[]prevS=prevSmaller(arr);int[]nextS=nextSmaller(arr);intmaxArea=0;// Calculate the area for each arrogram barfor(inti=0;i<arr.Length;i++){intwidth=nextS[i]-prevS[i]-1;intarea=arr[i]*width;maxArea=Math.Max(maxArea,area);}returnmaxArea;}staticvoidMain(){int[]arr={60,20,50,40,10,50,60};Console.WriteLine(getMaxArea(arr));}}
JavaScript
// JavaScript program to find the largest rectangular area possible // in a given histogram // Function to find next smaller for every elementfunctionnextSmaller(arr){constn=arr.length;// Initialize with n for the cases when next smaller// does not existconstnextS=newArray(n).fill(n);conststack=[];// Traverse all array elements from left to rightfor(leti=0;i<n;i++){while(stack.length&&arr[i]<arr[stack[stack.length-1]]){// Setting the index of the next smaller element// for the top of the stacknextS[stack.pop()]=i;}stack.push(i);}returnnextS;}// Function to find previous smaller for every elementfunctionprevSmaller(arr){constn=arr.length;// Initialize with -1 for the cases when prev smaller// does not existconstprevS=newArray(n).fill(-1);conststack=[];// Traverse all array elements from left to rightfor(leti=0;i<n;i++){while(stack.length&&arr[i]<arr[stack[stack.length-1]]){stack.pop();}if(stack.length){prevS[i]=stack[stack.length-1];}stack.push(i);}returnprevS;}// Function to calculate the maximum rectangular// area in the HistogramfunctiongetMaxArea(arr){constprevS=prevSmaller(arr);constnextS=nextSmaller(arr);letmaxArea=0;// Calculate the area for each arrogram barfor(leti=0;i<arr.length;i++){constwidth=nextS[i]-prevS[i]-1;constarea=arr[i]*width;maxArea=Math.max(maxArea,area);}returnmaxArea;}// Driver codeconstarr=[60,20,50,40,10,50,60];console.log(getMaxArea(arr));
Output
100
[Further Optimized] Using Single Stack - O(n) Time and O(n) Space
This approach is mainly an optimization over the previous approach.
When we compute next smaller element, we pop an item from the stack and mark current item as next smaller of it. One important observation here is the item below every item in stack is the previous smaller element. So we do not need to explicitly compute previous smaller.
Below are the detailed steps of implementation.
Create an empty stack.
Start from the first bar, and do the following for every bar arr[i] where 'i' varies from 0 to n-1
If the stack is empty or arr[i] is higher than the bar at top of the stack, then push 'i' to stack.
If this bar is smaller than the top of the stack, then keep removing the top of the stack while the top of the stack is greater.
Let the removed bar be arr[tp]. Calculate the area of the rectangle with arr[tp] as the smallest bar.
For arr[tp], the 'left index' is previous (previous to tp) item in stack and 'right index' is 'i' (current index).
If the stack is not empty, then one by one remove all bars from the stack and do step (2.2 and 2.3) for every removed bar
C++
// C++ program to find the largest rectangular area possible // in a given histogram #include<bits/stdc++.h>usingnamespacestd;// Function to calculate the maximum rectangular areaintgetMaxArea(vector<int>&arr){intn=arr.size();stack<int>s;intres=0;inttp,curr;for(inti=0;i<n;i++){while(!s.empty()&&arr[s.top()]>=arr[i]){// The popped item is to be considered as the // smallest element of the Histogramtp=s.top();s.pop();// For the popped item previous smaller element is // just below it in the stack (or current stack top)// and next smaller element is iintwidth=s.empty()?i:i-s.top()-1;res=max(res,arr[tp]*width);}s.push(i);}// For the remaining items in the stack, next smaller does// not exist. Previous smaller is the item just below in// stack.while(!s.empty()){tp=s.top();s.pop();curr=arr[tp]*(s.empty()?n:n-s.top()-1);res=max(res,curr);}returnres;}intmain(){vector<int>arr={60,20,50,40,10,50,60};cout<<getMaxArea(arr);return0;}
C
// C program to find the largest rectangular area possible // in a given histogram #include<stdio.h>#include<stdlib.h>// Stack structurestructStack{inttop;intcapacity;int*array;};// Function to create a stackstructStack*createStack(intcapacity){structStack*stack=(structStack*)malloc(sizeof(structStack));stack->capacity=capacity;stack->top=-1;stack->array=(int*)malloc(stack->capacity*sizeof(int));returnstack;}intisEmpty(structStack*stack){returnstack->top==-1;}voidpush(structStack*stack,intitem){stack->array[++stack->top]=item;}intpop(structStack*stack){returnstack->array[stack->top--];}intpeek(structStack*stack){returnstack->array[stack->top];}// Function to calculate the maximum rectangular areaintgetMaxArea(intarr[],intn){structStack*s=createStack(n);intres=0,tp,curr;// Traverse all bars of the arrogramfor(inti=0;i<n;i++){// Process the stack while the current element // is smaller than the element corresponding to // the top of the stackwhile(!isEmpty(s)&&arr[peek(s)]>=arr[i]){tp=pop(s);// Calculate width and update resultintwidth=isEmpty(s)?i:i-peek(s)-1;res=(res>arr[tp]*width)?res:arr[tp]*width;}push(s,i);}// Process remaining elements in the stackwhile(!isEmpty(s)){tp=pop(s);curr=arr[tp]*(isEmpty(s)?n:n-peek(s)-1);res=(res>curr)?res:curr;}returnres;}intmain(){intarr[]={60,20,50,40,10,50,60};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",getMaxArea(arr,n));return0;}
Java
// Java program to find the largest rectangular area possible // in a given histogram importjava.util.Stack;classGfG{// Function to calculate the maximum rectangular areastaticintgetMaxArea(int[]arr){intn=arr.length;Stack<Integer>s=newStack<>();intres=0,tp,curr;for(inti=0;i<n;i++){// Process the stack while the current element // is smaller than the element corresponding to // the top of the stackwhile(!s.isEmpty()&&arr[s.peek()]>=arr[i]){// The popped item is to be considered as the // smallest element of the Histogramtp=s.pop();// For the popped item, previous smaller element// is just below it in the stack (or current stack // top) and next smaller element is iintwidth=s.isEmpty()?i:i-s.peek()-1;// Update the result if neededres=Math.max(res,arr[tp]*width);}s.push(i);}// For the remaining items in the stack, next smaller does// not exist. Previous smaller is the item just below in// the stack.while(!s.isEmpty()){tp=s.pop();curr=arr[tp]*(s.isEmpty()?n:n-s.peek()-1);res=Math.max(res,curr);}returnres;}publicstaticvoidmain(String[]args){int[]arr={60,20,50,40,10,50,60};System.out.println(getMaxArea(arr));}}
Python
# Python program to find the largest rectangular area possible # in a given histogram # Function to calculate the maximum rectangular areadefgetMaxArea(arr):n=len(arr)s=[]res=0foriinrange(n):# Process the stack while the current element # is smaller than the element corresponding to # the top of the stackwhilesandarr[s[-1]]>=arr[i]:# The popped item is to be considered as the # smallest element of the Histogramtp=s.pop()# For the popped item, the previous smaller # element is just below it in the stack (or # the current stack top) and the next smaller # element is iwidth=iifnotselsei-s[-1]-1# Update the result if neededres=max(res,arr[tp]*width)s.append(i)# For the remaining items in the stack, next smaller does# not exist. Previous smaller is the item just below in# the stack.whiles:tp=s.pop()width=nifnotselsen-s[-1]-1res=max(res,arr[tp]*width)returnresif__name__=="__main__":arr=[60,20,50,40,10,50,60]print(getMaxArea(arr))
C#
// C# program to find the largest rectangular area possible // in a given histogram usingSystem;usingSystem.Collections.Generic;classGfG{// Function to calculate the maximum rectangular areastaticintgetMaxArea(int[]arr){intn=arr.Length;Stack<int>s=newStack<int>();intres=0,tp,curr;// Traverse all bars of the arrogramfor(inti=0;i<n;i++){// Process the stack while the current element // is smaller than the element corresponding to // the top of the stackwhile(s.Count>0&&arr[s.Peek()]>=arr[i]){tp=s.Pop();// Calculate width and update resultintwidth=s.Count==0?i:i-s.Peek()-1;res=Math.Max(res,arr[tp]*width);}s.Push(i);}// Process remaining elements in the stackwhile(s.Count>0){tp=s.Pop();curr=arr[tp]*(s.Count==0?n:n-s.Peek()-1);res=Math.Max(res,curr);}returnres;}publicstaticvoidMain(){int[]arr={60,20,50,40,10,50,60};Console.WriteLine(getMaxArea(arr));}}
JavaScript
// JavaScript program to find the largest rectangular area possible // in a given histogram // Function to calculate the maximum rectangular areafunctiongetMaxArea(arr){letn=arr.length;letstack=[];letres=0;// Traverse all bars of the arrogramfor(leti=0;i<n;i++){// Process the stack while the current element// is smaller than the element corresponding to// the top of the stackwhile(stack.length&&arr[stack[stack.length-1]]>=arr[i]){lettp=stack.pop();// Calculate width and update resultletwidth=stack.length===0?i:i-stack[stack.length-1]-1;res=Math.max(res,arr[tp]*width);}stack.push(i);}// Process remaining elements in the stackwhile(stack.length){lettp=stack.pop();letcurr=arr[tp]*(stack.length===0?n:n-stack[stack.length-1]-1);res=Math.max(res,curr);}returnres;}// Driver codeletarr=[60,20,50,40,10,50,60];console.log(getMaxArea(arr));
Output
100
[Alternate Approach] Using Divide and Conquer - O(n Log n) Time
The idea is to find the minimum value in the given array. Once we have index of the minimum value, the max area is maximum of following three values.
Maximum area in left side of minimum value (Not including the min value)
Maximum area in right side of minimum value (Not including the min value)
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.