Given an array of integers heights representing the histogram's bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram.

Example 1 Example 1 Input: heights = [2,1,5,6,2,3]
Output: 10
Explanation: The above is a histogram where width of each bar is 1.
The largest rectangle is shown in the red area, which has an area = 10 units.
Constraints:

Contents

When finding area of largest rectangle based on heights in the heights array, there could be 2 different scenarios

  1. If a smaller height comes after bigger height: For example if the heights are [2,1,3] Scenario 1 In this case, area that can be drawn from the first height 2, will be reduced to height 1 if it need to be included with next height which is 1.
  2. If a bigger height comes after smaller height: For example if the heights are [2,3] Scenario 2 In this case, area that can be drawn to the second height 3, we can include the smaller heights prior to that as well.

In this approach, we are going to use a Stack and store index, height pair in a monitonically increasing order, and compute area if we see a smaller height than previous and store that in a variable maxArea, and at the end go through the stack elements and compute area possible from each element until the end, we can get the total width possible using the index of that height. One thing that we do differently when storing the index is that, if there is a smaller height after a bigger height, since we are building monotonically increasing stack, we will pop the bigger height elements before adding the current one, but we store index as the last element that was popped, the reason we do that is because say if the input array is [2,1,3,1], before adding height 1 to the stack, we will pop height 2, and when storing 1 we will store it win index 1 since we can still take 1 unit height from the element height 2.

Let's look at an example, heights = [2, 1, 3, 1] Example with explanation

import java.util.Stack; public class LargestRectangleInHistogram { static int largestRectangleArea(int[] heights) { int maxArea = 0; Stack<int[]> indexToHeight = new Stack<>(); // monotonically increasing order for(int i=0; i<heights.length; i++) { int startIndex = i; int height = heights[i]; while(!indexToHeight.isEmpty() && indexToHeight.peek()[1] > height) { // if top of the stack height is greater than current one, then we cannot extend previous height int[] indexHeight = indexToHeight.pop(); int indexE = indexHeight[0]; int heightE = indexHeight[1]; maxArea = Math.max(maxArea , ((i - indexE) * heightE)); startIndex = indexE; } indexToHeight.push(new int[]{startIndex, height}); } // in the above loop, it may not have computed maxArea if the array is in increasing order for(int[] indexHeight : indexToHeight) { maxArea = Math.max(maxArea, indexHeight[1] * (heights.length - indexHeight[0])); } return maxArea; } public static void main(String[] args) { System.out.println(largestRectangleArea(new int[]{2,1,5,6,2,3})); System.out.println(largestRectangleArea(new int[]{2,4})); } }
Complexity Analysis:

Time complexity: Time complexity for the solution will be O(n) where n is the length of input array heights.
Space complexity: O(n) for storing elements into stack.

Above implementations source code can be found at GitHub link for Java code