【LeetCode】84. The largest rectangle in the histogram

topic

Given  n  non-negative integers, used to represent the height of each column in the histogram. Each column is adjacent to each other and has a width of 1.

Find the maximum area of ​​the rectangle that can be outlined in the histogram.

Example 1:

Input: heights = [2,1,5,6,2,3]
 Output: 10
 Explanation: The largest rectangle is the red area in the figure, with an area of ​​10

Example 2:

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

hint:

  • 1 <= heights.length <=10^5
  • 0 <= heights[i] <= 10^4

answer

source code

class Solution {
    public int largestRectangleArea(int[] heights) {
        int[] left = new int[heights.length];
        int[] right = new int[heights.length];
        Deque<Integer> stack = new ArrayDeque<>();

        for (int i = 0; i < heights.length; i++) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                stack.pop();
            }

            left[i] = (stack.isEmpty() ? -1 : stack.peek());
            stack.push(i);
        }

        stack.clear();

        for (int i = heights.length - 1; i > -1; i--) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                stack.pop();
            }

            right[i] = (stack.isEmpty() ? heights.length : stack.peek());
            stack.push(i);
        }

        int res = 0;
        for (int i = 0; i < heights.length; i++) {
            res = Math.max(res, (right[i] - left[i] - 1) * heights[i]);
        }

        return res;
    }
}

Summarize

The height of the largest rectangle must be the height of a certain column, so we only need to extend the height of each column to both sides, record the maximum width they can reach, and calculate the area of ​​the rectangle.

Although violent enumeration can also be used to find the pillars that are smaller than it and closest to it on both sides of a certain pillar, this is obviously not elegant, and it is definitely not the best solution.

In order to skip unnecessary comparisons, all we need is a "monotonic stack". The subscript corresponding to the pillar is stored in the stack. From the bottom of the stack to the top of the stack, the subscript increases monotonically, and the height of the pillar corresponding to the subscript also increases monotonically. When traversing to a certain column from left to right, compare it with the height of the column corresponding to the subscript on the top of the stack. If it is lower than or equal to the corresponding column on the top of the stack, pop the stack until the column is higher than the corresponding column on the top of the stack. Then at this time The column corresponding to the subscript on the top of the stack is the column to the left of the current column that is smaller than it and closest to it. Similarly, get the one on the right.

In this way, after two traversals, we can get the borders on the left and right sides of each column. There is a special case here, if there are no columns lower than itself on the left and right sides, then set the border to 0 / heights.length. Then calculate the rectangular area obtained by taking the height of each column as the height of the rectangle, compare and select the largest area.

Guess you like

Origin blog.csdn.net/qq_57438473/article/details/132618594