×

The Maximum Rectangular Area in a Histogram in Java

Continuous bars should be used to form the largest possible rectangle. We'll assume in the interest of convenience that each bar's width is 1.

Naive Approach

In this method, each bar will be taken into account as the initial point one at a time, and from there, the rectangle area will be computed again by taking the subsequent bars one at a time. Every time the rectangle area is calculated, it is compared to the greatest area currently available 

Example program

// program for the maximum rectangular area in a histogram in java using a naive approach

public class LargestRectArea
{  
int findMin(int a, int b)  
{  
  int min = (a > b) ? b : a;   
  return min;  
}  
int findMax(int a, int b)  
{  
  int max = (a > b) ? a : b;   
  return max;  
}  
public static void main(String argvs[])  
{  
LargestRectAreaobj = new LargestRectArea();  
int arr[] = {8, 4, 7, 6, 7, 3, 7};  
int n = arr.length;  
 int maxArea = 0;  
for(int i = 0; i< n; i++)  
{  
int temp = arr[i];  
maxArea = obj.findMax(temp, maxArea);  
for(int j = i + 1; j < n; j++)  
{  
    temp = obj.findMin(temp, arr[j]);  
maxArea = obj.findMax(maxArea, temp * (j - i + 1));  
}  
}  
System.out.println("The maximum rectangular area is: " + maxArea);  
}  
}   

Output

The maximum rectangular area is: 21

Analysis of complexity

Time Complexity: We utilized nested for-loops of degree 2 in the program above. As a result, the program described above has an overall complexity of O(n2), where n represents the number of entries in the given array.

Divide and Conquer Approach

The idea is to locate the index of the least level in the input array. The greatest area is the largest of the next three values after we have determined the indices of the number that is minimum.

  • A maximum area is located to the left of the lower limit 
  • maximum-sized region to the right of the lower limit 
  • multiplied by the lowest bar value, the total number of bars.

Example program

//program for the maximum rectangular area in a histogram in java using the divide and conquer technique

import java.util.*;  
public class LargestRectArea1  
{  
static int hist[];  
static int segTree[];  
public int max(int a, int b, int c)  
{ returnMath.max(Math.max(a, b), c); } 
public int findMin(int a, int b)  
{  
if (a == -1)  
{ return b; }  
if (b == -1) { return a; }  
return (hist[a] < hist[b]) ? a : b;  
}  
public int findMid(int s, int e)  
{ return s + (e - s) / 2; }
public int findIndexUtility( intsi, int ei, int qs, int qe, int idx)  
{  
if (qs<= si&&qe>= ei)  
{  
return segTree[idx];  
} 
if (ei<qs || si>qe)  
{  
return -1;  
} 
int mid = findMid(si, ei);  
return findMin( findIndexUtility(si, mid, qs, qe, 2 * idx + 1),  
findIndexUtility( mid + 1, ei, qs, qe, 2 * idx + 2));  
}  
public int returnIndex( int s, int qb, int qe)  
{  
if (qb< 0 || qe> s - 1 || qb>qe)  
{  
System.out.print("The given input is not valid");  
return -1;  
}  


return findIndexUtility( 0, s - 1, qb, qe, 0);  
}  
public int constructSTUtililty(int s, int e, int si)  
{ 
if (s == e)  
{  
return (segTree[si] = s);  
} 
int mid = findMid(s, e);  
segTree[si] = findMin(constructSTUtililty(s, mid, si * 2 + 1),  
constructSTUtililty(mid + 1, e, si * 2 + 2));  
return segTree[si];  
} 
public void constructSegTree(int s)  
{ 
int x = (int)(Math.ceil(Math.log(s)));
int maxSize = 2 * (int)Math.pow(2, x) - 1;
segTree = new int[maxSize * 2];  
constructSTUtililty( 0, s - 1, 0);  
} 
public int findMaxAreaRec( int s, int lt, int rt)  
{ 
if (lt>rt)  returnInteger.MIN_VALUE;  
if (lt == rt)  return hist[lt]; 
int i = returnIndex(s, lt, rt);  
return max(findMaxAreaRec(s, lt, i - 1), findMaxAreaRec( s, i + 1, rt), (rt - lt + 1) * (hist[i]));  
}  
public int computeMaxArea( int s)  
{  
constructSegTree(s);  
return findMaxAreaRec(s, 0, s - 1);  
}  
public static void main(String[] argvs)  
{  
int[] arr = {7, 2, 6, 5, 6, 2, 7};  
int s = arr.length;  
hist = new int[s];  
LargestRectArea1 obj = new LargestRectArea1();  
hist = arr;  
System.out.println("The maximum rectangular area is: " + obj.computeMaxArea(s));  
}  
}   

Output

The maximum rectangular area is: 15

Analysis of complexity

The above program's time complexity depends on the segment tree and locating the largest rectangle area, respectively. The segment tree construction process takes O(n) time, whereas determining the largest rectangle region takes O(log(n)) time. As a result, the time complexity changes to O(n) + O(n*log(n)), and asymptotically, it changes to O(n*log(n)), where n is the maximum number of entries in the input array.

Using Stack

Let's examine the stack-based approach for locating the rectangle area.

Step 1: A stack is the first step in pushing and popping items.

Step 2: Starting with the first bar, complete the task "histArr[j]" for each subsequent bar, where "j" ranges from 0 to s–1.

Push "j" to the stack if there are no elements in the stack or if histArr[ij] is longer than the bar at the top of the stack.

Continue popping bars from the top of the stack until the bar at the top of the stack is higher if the existing bar is smaller than the bar that is existing there. Assume that histArr[top] is the removed bar. Calculate the rectangle's area using the smallest bar, histArr[top]. The preceding bar in the stack is the "left index" for the histArr[top], and the "right index" is "j." (the current index).

Step 3: If indeed the stack contains any bars, remove them one at a time from the stack by repeating step 2(ii) for each bar that was taken out.

Example program

import java.util.Stack;
public class LargestRectArea2  
{ 
public int findMaxArea(int histArr[], int s)  
{ 
Stack<Integer>stk = new Stack<>();  


int maxArea = 0;
int top;
int areaWithTop;
int j = 0;  
while (j < s)  
{ 
if (stk.empty() || histArr[stk.peek()] <= histArr[j])  
stk.push(j++);  
else  
{  
top = stk.peek();
stk.pop();
areaWithTop = histArr[top] * (stk.empty() ? j : j - stk.peek() - 1);  
if (maxArea<areaWithTop)  
{  
maxArea = areaWithTop;  
}  
}  
} 
while (stk.empty() == false)  
{  
top = stk.peek();  
stk.pop();  
areaWithTop = histArr[top] * (stk.empty() ? j : j - stk.peek() - 1);  
  if (maxArea<areaWithTop)  
maxArea = areaWithTop;  
}  
  return maxArea;  
}  
public static void main(String[] args)  
{  
int[] histArr = {8, 9, 7, 6, 7, 3, 8};  
int s = histArr.length;
LargestRectArea2 obj = new LargestRectArea2();  
System.out.println("The maximum rectangular area is: " + obj.findMaxArea(histArr, s));  
}  
}   

 Output

The maximum rectangular area is: 30

Using Auxiliary Arrays

Another strategy is to use two auxiliary arrays to determine the previous smaller bar and the following smaller bar for each bar in the histogram. See the algorithm below.

Step 1: Initialize the two auxiliary arrays leftSmaller[] as well as rightSmaller[] with a negative sign and n, respectively.

Step 2: In the rightSmaller[] as well as leftSmaller[] arrays, we maintain the indexes of the subsequent and preceding smaller elements for each element, respectively. O(n) time is required.

Step 3: Using the jth bar, which is the smallest in the range remaining, we calculate the area for each bar.Smaller and to the right smaller[j] then multiplying it by the left-hand side difference Smaller and to the rightSmaller[j].

Step 4: By comparing the areas of each bar, the maximum area may be calculated. In step 3, the area for each of the several bars is calculated.

Example program

import java.util.Stack;  
public class LargestRectArea3  
{ 
public int findMaxArea(int a[], int s)  
{ 
Stack<Integer>stk = new Stack<>();  
stk.push(-1);  
int maxArea = a[0];  
int leftSmaller[] = new int[s];  
int rightSmaller[] = new int[s];  
for (int j = 0; j < s; j++)  
{  
leftSmaller[j] = -1;  
rightSmaller[j] = s;  
}  


int j = 0;  
while (j < s)  
{  
while(!stk.empty() &&stk.peek() != -1 && a[j] < a[stk.peek()] 
{ 
rightSmaller[stk.peek()] = (int)j;  
stk.pop();  
}  
if(j > 0 && a[j] == a[(j - 1)])  
{ 
leftSmaller[j] = leftSmaller[(int)(j - 1)];  
}  
else  
{ 
leftSmaller[j] = stk.peek();  
}  
stk.push(j);  
j = j + 1;  
}  




for(j = 0; j < s; j++)  
{ 
maxArea = Math.max(maxArea, a[j] * (rightSmaller[j] - leftSmaller[j] - 1));  
}  


return maxArea;  
}  
public static void main(String argvs[])  
{  
int[] histArr = {7, 2, 6, 5, 6, 2, 7};  
int size = histArr.length;


LargestRectArea3 obj = new LargestRectArea3();  
System.out.println("The maximum rectangular area is: " + obj.findMaxArea(histArr, size));  
}  
}   

Output

The maximum rectangular area is: 30

Analysis of the complexity

The final two methods have an O(n) time complexity, where n is the total amount of elements in the array.


Related Topics

Mutable class in Java

A language for object-oriented programming is Java. Because this is an object-oriented language of programming, all of its mechanisms and methods are based on objects. Java has a concept of...

6 minutes read.

Java Command Line Arguments

Java command line arguments Command line argument is an input or argument to the program when you run the program. In Java, we can take the inputs from the console, and...

2 minutes read.

Computing Digit Sum of all Numbers from 1 to n in Java

In this tutorial, we will discuss various methods to compute the sum of digits of all numbers beginning from 1 to n through a Java program. We will achieve it through...

7 minutes read.

Timestamp Operation in Java

JDBC escape syntax is supported by Timestamp's formatting and parsing functions. Additionally, it adds support for fractional seconds values for SQL TIMESTAMP.java.util.Date is wrapped in a lightweight wrapper that enables...

3 minutes read.

Java Integer rotateLeft() method

The rotateLeft() method of Java Integer class returns the value obtained by rotating the  2’s complement binary representation of the given integer value left by the specified number of bits. Syntax public...

1 minute read.

Java Externalization

What is Externalization in Java? Externalization is a concept that is advanced to serialization. Serialization is a concept where we can transfer an object from our JVM ( Java virtual machine...

3 minutes read.

Java String toUpperCase() methods

Java String toUpperCase() method is used to convert all the characters of the String into upper case. Syntax public String toUpperCase() public String toUpperCase(Locale locale) Returns It returns upper case String. Java String toUpperCase() Example 1: public...

1 minute read.

Difference between String Tokenizer and split Method in Java

Introduction Today, let us understand the difference between String Tokenizer and Split Method. First, let us learn about the String Tokenizer and Split method individually and then know about their differences String...

7 minutes read.

Client Server Program in Java

Client Server Program in Java The client and server are the two main components of socket programming. The client is a computer/node that request for the service and the server is...

7 minutes read.

XOR Binary Operator in Java

One of the various Bitwise operators in Java is ava XOR. If two boolean operands are given, the XOR (also known as exclusive OR) returns true. When both of the...

4 minutes read.

Singleton Design Pattern in Java

In the singleton pattern, a class that only has one instance and offers a universal point of access is taken into consideration. It can also be defined in another way, a...

4 minutes read.

Java Integer numberOfTrailingZeros() method

The numberOfTrailingZeros()  method of Java Integer class returns the total number of zero bits following the lowest-order one-bit in the 2’s complement binary representation of the specified int value. Syntax public static...

1 minute read.

AbstractSet Class in Java

The AbstractSet class is used for the implementation of the Abstract Collection class and interface. It is the part of Collection Frameworks. In the AbstractSet, the implementation is same as the...

3 minutes read.

Interchange Diagonal elements in Java

In this article, you will be very well acknowledged about what is a matrix with an example. You will also be acknowledged about how to interchange the diagonal elements in...

4 minutes read.

Applet Life Cycle in Java

In this article, we are going to acknowledge you about what a applet is, what is its life cycle and stages in life cycle, along with the syntax and example...

4 minutes read.

Converting Roman to Integer Numerals in java

In this article, you will be acknowledged about the process of conversion of roman numbers to integers in java. The most important approaches are discussed and also the implementation of...

3 minutes read.

String vs StringBuilder

String vs StringBuilder In this section, we will discuss the comparison between Java String and StringBuilder class. String In Java, a string is treated as an object that represents a sequence of characters....

4 minutes read.

Convert Char array to string in java

A collection of characters is referred to as a string. A character array differs from a string in that the string is canceled by the special character "\0." A string...

4 minutes read.

Java Editors

A straightforward text editor may be used to create Java applications. However, a Java integrated programming environment (IDE) enables the software developer to create programs more quickly. An IDE offers...

4 minutes read.

POJO in Java

Plain old Java Object, in short, is called POJO in Java. POJO is an everyday object that is not subject to any specific limitations. We can use POJO in any Java...

3 minutes read.