LeetCode 84:柱狀圖中最大的矩形(單調棧)

題目

給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度爲 1 。求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。

示例

輸入: [2,1,5,6,2,3]
輸出: 10
在這裏插入圖片描述

代碼

暴力法

遍歷每根柱子,以當前柱子 i 的高度作爲矩形的高,那麼矩形的寬度邊界即爲向左找到第一個高度小於當前柱體 i 的柱體,向右找到第一個高度小於當前柱體 i 的柱體。
對於每個柱子我們都如上計算一遍以當前柱子作爲高的矩形面積,最終比較出最大的矩形面積即可。

class Solution {
    public int largestRectangleArea(int[] heights) {
        int res = 0;
        for(int i=0;i<heights.length;i++){
            int h = heights[i];
            int w = 1;
            int j = i-1;
            //先遍歷左邊
            while(j>=0&&heights[j]>=h){
                w++;
                j--;
            }
            j = i+1;
            //遍歷右邊
            while(j<heights.length&&heights[j]>=h){
                w++;
                j++;
            }
            res = Math.max(res,w*h);
        }
        return res;
    }
}

單調棧

我們每遍歷到當前柱體 i 時:
上述寫法中,我們需要再嵌套一層 while 循環來向左找到第一個比柱體 i 高度小的柱體,這個過程是 O(N) 的;
那麼我們可以 O(1) 的獲取柱體 i 左邊第一個比它小的柱體嗎?答案就是單調增棧,因爲對於棧中的柱體來說,棧中下一個柱體就是左邊第一個高度小於自身的柱體

因此遍歷每個柱體,若當前的柱體高度大於等於棧頂柱體的高度,就直接將當前柱體入棧,否則若當前的柱體高度小於棧頂柱體的高度,說明當前棧頂柱體找到了右邊的第一個小於自身的柱體,那麼就可以將棧頂柱體出棧來計算以其爲高的矩形的面積了。

class Solution {
    public int largestRectangleArea(int[] heights) {
        
        int[] array = new int[heights.length+2];
        System.arraycopy(heights,0,array,1,heights.length);
        int res = 0;
        //
        LinkedList<Integer> stack = new LinkedList<>();
        for(int i=0;i<array.length;i++){
            
            while(!stack.isEmpty()&&array[i]<array[stack.peek()]){
                /*如果當前柱體高度小於棧頂柱體的高度,
                說明當前棧頂柱體找到了右邊的第一個小於自身的柱體,
                那麼以它爲高度的矩形面積可求
                */
                int index = stack.pop();
                res = Math.max(res,(i-stack.peek()-1)*array[index]);
            }
            /*棧頂柱體爲左邊第一個高度小於當前柱體的柱體,
            若當前的柱體高度大於等於棧頂柱體的高度,就直接將當前柱體入棧
            */
            stack.push(i);
        }
        return res;
    }
}

ps:這道題跟“接雨水”思想是一樣的:單調棧

參考鏈接:詳解單調棧,🤷‍♀️必須秒懂!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章