Maximum Rectangular Area in a Histogram in Java

In this section, we will see how one can compute the maximum rectangular area in the histogram.

What is maximum rectangular area in the histogram?

The maximum rectangle that has to be created should be made of continuous bars. For the sake of simplicity, we will assume that the width of each bar is 1.

For example, for the following histogram that has 7 bars of the heights {7, 3, 6, 5, 6, 2, 7}, the maximum rectangular area, which is possible, is 15. The maximum area is highlighted in yellow color.

Maximum Rectangular Area in a Histogram in Java

Let's discuss the various approaches to solve this problem.

Naïve Approach

In this approach, we will consider each bar one by one as the starting point, and from the starting point, we will compute the rectangular area each time by taking the next coming bar one by one. Every time we compute the rectangular area, we compare it with the current maximum area (initially, the maximum area is initialized with 0).

FileName: LargestRectArea.java

Output:

The maximum rectangular area is: 15

Time Complexity: In the above program, we have used the nested for-loops of degree 2. Therefore, the total complexity of the above program is O(n2), where n is the total number of elements present in the input array.

Divide and Conquer Approach

The concept is to find the index of a value in the input array that is minimum. Once we have found the index of the value that is minimum, the maximum area is the maximum of the following three values.

  1. Area that is maximum on the left side of the minimum value (excluding the minimum value)
  2. Area that is maximum on the right side of the minimum value (excluding the minimum value).
  3. Total count of bars multiplied by the minimum bar value.

Observe the following program.

Output:

The maximum rectangular area is: 15

Time Complexity: In the above program, the time complexity is dependent on two things: one is the segment tree, and the second is finding the maximum rectangular area. The time complexity consumed in building the segment tree is O(n) and for finding the maximum rectangular area, the time complexity is O(log(n)). Thus, the time complexity becomes O(n) + O(n * log(n)), and asymptotically the time complexity becomes O(n * log(n)), where n is the total number of elements present in the input array.

If we compare the above two programs, we find that the latter one is more optimized as it takes less time to solve the problem. However, we can even optimize it furthermore. Let's see it in the following approach.

Approach: Using Stack

Let's see the algorithm for finding the rectangular area using stack.

Step 1: Create a stack for pushing and popping elements.

Step 2: Begin from the first bar, and perform the following task for every bar "histArr[j]" where 'j' varies from 0 to s - 1.

  1. If the stack is containing zero elements or histArr[ij] is longer than the bar present at the top of the stack, then push 'j' to the stack.
  2. If the current bar is shorter than the bar present at the top of stack, then keep popping the bars from the top of stack until the bar present at the top of the stack is larger. Assume that the removed bar is histArr[top]. Compute the rectangle area with histArr[top] as the smallest bar. For the histArr[top], the 'left index' is the previous (previous to top) bar in the stack, and the 'right index' is 'j' (the current index).

Step 3: If the stack is containing some bars, pop all the bars one by one from the stack and repeat step 2(ii) for every removed bar.

FileName: LargestRectArea2.java

Output:

The maximum rectangular area is: 15

By Using Auxiliary Arrays

Another approach is to find the previous smaller and the next smaller bar, for every bar present in the histogram, and it will be achieved using two auxiliary arrays. See the following algorithm.

Step 1: First, we take two auxiliary arrays leftSmaller[] and rightSmaller[] and initialize them with a negative number and n, respectively.

Step 2: For each element, we keep the index of the next smaller and the previous smaller element in rightSmaller[] and leftSmaller[] arrays, respectively. It takes O(n) time.

Step 3: For each bar, we compute the area by taking the jth bar as the shortest in the range leftSmaller[j] and rightSmaller[j] and multiplying it with the difference of leftSmaller[j] and rightSmaller[j].

Step 4: The maximum area can be computed by comparing the area for each bar. The area for the different bars is computed in step 3.

FileName: LargestRectArea3.java

Output:

The maximum rectangular area is: 15

Time Complexity: The time complexity of the last two approaches is O(n), where n is the total number of elements present in the array.