84. Largest Rectangle in Histogram

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.

1
2
3
4
5
6
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.

ex1

1
2
3
4
Example 2:

Input: heights = [2,4]
Output: 4

ex2

Constraints:

  • 1 <= heights.length <= 105
  • 0 <= heights[i] <= 104

Solution

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
class Solution {
    
    public int largestRectangleArea(int[] heights) {
        int max = 0;
        Stack<Integer> posStack = new Stack<>();
        Stack<Integer> heightStack = new Stack<>();
        
        for (int right = 0; right <= heights.length; right++) {
            int rightHeight = (right == heights.length) ? 0: heights[right];
            
            while (posStack.size() > 0 && heightStack.peek() > rightHeight) {
                int left = posStack.pop();
                int leftHeight = heightStack.pop();
                int sideLength = posStack.size() > 0 ? (right - posStack.peek() - 1): right;
                int square = leftHeight * sideLength;
                // System.out.printf("[%d,%d] = %d %n", sideLength, right, square);
                max = Math.max(max, square);
            }
            
            int left = 0;
            int minHeight = rightHeight;
            if (posStack.size() > 0) {
                left = posStack.peek();
                minHeight = heightStack.peek();
            } 
            int square = minHeight * (right - left - 1);
            // System.out.printf("last [%d,%d] = %d %n", left, right, square);
            max = Math.max(max, square);
            
            posStack.push(right);
            heightStack.push(rightHeight);
        }
        return max;
    }
    
    public int largestRectangleArea1(int[] heights) {
        int max = 0;
        Stack<Integer> posStack = new Stack<>();
        Stack<Integer> heightStack = new Stack<>();
        
        for (int i = 0; i <= heights.length; i++) {
            int h = (i == heights.length) ? 0: heights[i];
            
            while (posStack.size() > 0 && heightStack.peek() > h) {
                int left = posStack.pop();
                int leftHeight = heightStack.pop();
                int sideLength = posStack.size() > 0 ? (i - posStack.peek() - 1): i;
                int square = leftHeight * sideLength;
                System.out.printf("[%d,%d] = %d %n", sideLength, i, square);
                max = Math.max(max, square);
            }
            
            posStack.push(i);
            heightStack.push(h);
        }
        while (posStack.size() > 0) {
            int right = posStack.pop();
            int rightHeight = heightStack.pop();
            
            int left = 0;
            int minHeight = rightHeight;
            if (posStack.size() > 0) {
                left = posStack.peek();
                minHeight = heightStack.peek();
            } 
            int square = minHeight * (right - left - 1);
            System.out.printf("last [%d,%d] = %d %n", left, right, square);
            max = Math.max(max, square);
        }
        return max;
    }

     public int largestRectangleArea2(int[] heights) {
        int max = 0;
        for (int i = 0; i < heights.length; i++) {
            for (int j = i; j < heights.length; j++) {
                int minH = heights[i];
                for (int k = i; k <= j; k++) {
                    minH = Math.min(heights[k], minH);
                }
                int square = minH * (j - i + 1);
                // System.out.printf("[%d,%d] = %d %n", i, j, square);
                max = Math.max(max, square);
            }
        }
        
        return max;
    }
    
    public int largestRectangleArea3(int[] heights) {
        int max = 0;
        for (int i = 0; i < heights.length; i++) {
            int h = heights[i];
            int minH = h;
            for (int j = i; j < heights.length; j++) {
                minH = Math.min(heights[j], minH);
                int square = minH * (j - i + 1);
                max = Math.max(max, square);
                System.out.printf("[%d,%d] = %d %n", i, j, square);
            }
        }
        return max;
    }
}