60-单调栈-柱状图中的最大矩形

84.柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。

1 动态规划+双指针解法

找到并记录左边第一个小于该数值的下标,右边第一个小于该数值的下标。
注意:初始化是有原因的,正好保证计算maxRightIndex[i] – minLeftIndex[i] – 1 的时候不存在任何的特殊情况,都能一致对待。

class Solution {
    public int largestRectangleArea(int[] heights) {
        //双指针+动态规划,记录左边第一个小于该数值的下标,右边第一个小于该数值的下标
        int len = heights.length;
        int[] minLeftIndex = new int[len];
        int[] maxRightIndex = new int[len];
        minLeftIndex[0] = -1;//为什么这样初始化呢?
        for(int i = 1; i < len; i ++){
            int t = i - 1;
            while(t >= 0 && heights[t] >= heights[i]){
                t = minLeftIndex[t];
            }
            minLeftIndex[i] = t;
        }
        maxRightIndex[len - 1] = len;
        for(int i = len - 2; i >= 0; i --){
            int t = i + 1;
            while(t < len && heights[t] >= heights[i]){
                t = maxRightIndex[t];
            }
            maxRightIndex[i] = t;
        }
        int res = 0;
        for(int i = 0; i < len; i ++){
            int w = maxRightIndex[i] - minLeftIndex[i] - 1;
            int h = heights[i];
            res = Math.max(res, w * h);
        }
        return res;
    }
}

2 单调栈

一开始忘记了第三种情况的push语句。
还有思考数组长度。

class Solution {
    public int largestRectangleArea(int[] heights) {
        //保证栈的递增顺序,找到左侧和右侧不小于mid的下标。
        int len = heights.length;
        int[] newHeights = new int[len + 2];
        for(int i = 1; i <= len; i ++){
            newHeights[i] = heights[i - 1];
        }
        heights = newHeights;
        int res = heights[1];
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);
        for(int i = 1; i <= len + 1; i ++){
            if(heights[i] > heights[stack.peek()]){
                stack.push(i);
            }else if(heights[i] == heights[stack.peek()]){
                stack.pop();
                stack.push(i);
            }else{
                while(heights[i] < heights[stack.peek()]){
                    int mid = stack.pop();
                    int left = stack.peek();
                
                    int w = i - left - 1;
                    int h = heights[mid];
                    //System.out.println(left);
                    //System.out.println(i);
                    //System.out.println(h);
                    //System.out.println("");
                    res = Math.max(res, h * w);
                }
                stack.push(i);
            }
        }
        return res;
    }
}

版权声明:本文为weixin_48494477原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。