算法修炼Day60|84.柱状图中最大的矩形

92 阅读1分钟

LeetCode:84. 柱状图中最大的矩形 - 力扣(LeetCode)

1.思路

方法一:暴力解法。以当前节点为基准,向左右进行双向遍历,找出当前高度下的最大范围下的值,循环遍历比较得出得出最大值。

方法二:单调栈法。求连续柱子中所能笼盖的最大面积。基本思想和方法一一致:以每个元素为基准获取左右两侧小于该元素的位置,求得这段距离的面积。具体实现上维持一个单调递减的单调栈,单调递减是结果,当小于当前元素就直接进行计算而不是入栈了。

两种计算情况,当high[i] >= high[stack.peek()],直接入栈,反之进行循环操作。

另外,注意数组左右两侧需要加入数值0,避免单调数字排列没有进行计算的条件。

2.代码实现
// 暴力解法
class Solution {
    public int largestRectangleArea(int[] heights) {
        int len = heights.length;
        if (len == 0) {
            return len;
        }
        int res = 0;
        // 以当前元素高度为基准的最大面积
        for (int i = 0; i < len; i++) {
            // 向左遍历
            int left = i;
            int curHeight = heights[i];
            while (left > 0 && heights[left - 1] >= curHeight) {
                left--;
            }
            // 向右遍历
            int right = i;
            while (right < len - 1 && heights[right + 1] >= curHeight) {
                right++;
            }
            int s = curHeight * (right - left + 1);
            res = Math.max(s, res);
        }
        return res;
    }
}
// 单调栈法
class Solution {
    public int largestRectangleArea(int[] heights) {
        int result = 0;
        int[] high = new int[heights.length + 2];
        for (int i = 1; i <= heights.length; i++) {
            high[i] = heights[i - 1]; 
        }
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        for (int i = 1; i < high.length; i++) {
            if (high[i] >= high[stack.peek()]) {
                stack.push(i);
            } else {
                while (!stack.isEmpty() && high[i] < high[stack.peek()]) {
                    int mid = stack.pop();
                    if (!stack.isEmpty()) {
                        int left = stack.peek();
                        int diff = i - left - 1;
                        int s = diff * high[mid];
                        result = Math.max(result, s);
                    }
                 }
                 stack.push(i);
            }
        }
        return result;
    }
}
3.复杂度分析

时间复杂度:O(N^2).

空间复杂度:O(N).