每日一題——柱狀圖中最大的矩形

菜雞每日一題系列打卡84

每天一道算法題目 

小夥伴們一起留言打卡

堅持就是勝利,我們一起努力!

題目描述(引自LeetCode)

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

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

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

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

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

題目分析

這道題目最容易想到的是暴力法,通過雙重for循環枚舉高度(或者寬度),從而得到柱狀圖中最大的矩形,但基於暴力搜索的時間複雜度爲O(n^2),我們需要對此進行優化。

這時候就需要用到一種經典的數據結構——單調棧,其實就是一種棧,只不過其中的元素是有序的。值得注意的是,通過單調棧維護小於柱子i的高度值,需要注意棧爲空時設置哨兵。

話不多說,上代碼!

代碼實現

class Solution {


    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) return 0;


        int length = heights.length;
        int[] left = new int[length];
        int[] right = new int[length];
        Arrays.fill(right, length);


        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < length; i++) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) right[stack.pop()] = i;
            left[i] = stack.isEmpty() ? -1 : stack.peek();
            stack.push(i);
        }


        int result = 0;
        for (int i = 0; i < length; i++) {
            int tmp = (right[i] - left[i] - 1) * heights[i];
            if (tmp > result) result = tmp;
        }
        return result;
    }


}

代碼分析

對代碼進行分析,程序採用了單調棧進行實現,每一個位置只會入棧一次(在枚舉到它時),並且最多出棧一次,因此單調棧的時間複雜度爲O(n);而就空間而言,採用了額外的數組空間和單調棧空間,空間複雜度爲O(n)。

執行結果

學習 | 工作 | 分享

????長按關注“有理想的菜雞

只有你想不到,沒有你學不到

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