1. 程式人生 > >LeetCode-84.柱狀圖中最大的矩形(相關話題:棧)

LeetCode-84.柱狀圖中最大的矩形(相關話題:棧)

給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。

求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。

以上是柱狀圖的示例,其中每個柱子的寬度為 1,給定的高度為 [2,1,5,6,2,3]。

圖中陰影部分為所能勾勒出的最大矩形面積,其面積為 10 個單位。

示例:

輸入: [2,1,5,6,2,3]
輸出: 10

解題思路:單調棧,其實也就是正常的棧,只不過棧中的元素是單調遞減/遞增的,若當前處理元素小於/大於棧頂元素,則入棧,否則作相應處理。

對於題中給出的示例,處理過程如下:(輸入int[] heights,定義變數int s,棧stack)

  1. 依次處理輸入陣列heights[]
  2. 判斷棧是否為空,若為空,則將當前處理元素的下標入棧,若不為空,判斷當前元素是否大於等於棧頂元素(即判斷是否heights[i] > heights[stack.peek()])
  3. 若大於,則將當前元素下標入棧,處理下一元素
  4. 若小於,將棧頂元素topIndex出棧,判斷棧是否為空,若為空,則s = Math.max(s, i * heights[topIndex]);若不為空,則s = Math.max(s, (i-stack.peek()-1)*heights[topIndex]);回到步驟2
  5. (處理完輸入陣列heights[])判斷棧是否為空
  6. 若不為空,彈出棧頂元素topI

java程式碼:

class Solution {
    public int largestRectangleArea(int[] heights) {
        int s = 0;
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < heights.length; i++) {
            //單調棧,保證棧中元素單調遞增
            if(stack.isEmpty() || heights[i] >= heights[stack.peek()]) {
                stack.push(i);
                continue;
            }

            while(!stack.isEmpty() && heights[stack.peek()] > heights[i]) {
                int topIndex = stack.pop();
                if(stack.isEmpty()) {
                    s = Math.max(s, i * heights[topIndex]);
                } else {
                    s = Math.max(s, (i-stack.peek()-1)*heights[topIndex]);
                }
            }
            stack.push(i);
        }

        //為保證所有高度都處理完,比如原陣列為遞增序列,最後用0做一次處理
        while(!stack.isEmpty()) {
            int topIndex = stack.pop();
            if(stack.isEmpty()) {
                s = Math.max(s, heights.length * heights[topIndex]);
            } else {
                s = Math.max(s, (heights.length - stack.peek()-1)*heights[topIndex]);
            }
        }

        return s;
    }
}