day60|84.柱状图中最大的矩形

文章目录

  • 84.柱状图中最大的矩形

84.柱状图中最大的矩形

注意的点:

  1. 暴力破解的思路就是单调栈的思路,只不过单调栈的方式是用空间换取时间。
  2. 可以使用“哨兵”处理数组的首尾。
  3. 求局部矩形的宽度时一定要先将当前栈顶元素出栈,否则会在求原数组的最后一个元素时有问题。

以下是代码部分:

public class 柱状图中最大的矩形84 {

    //暴力破解
    //思路: 固定高度,求宽度(从当前i开始向两边找宽度)
    //超时了
    public int largestRectangleArea(int[] heights) {

        int result = 0;
        int left, right;

        for (int i = 0; i < heights.length; i++) {

            left = i;
            right = i;

            //寻找左边界
            while (left-1 >= 0 && heights[left-1] >= heights[i])
                left--;

            //寻找右边界
            while (right+1 < heights.length && heights[right+1] >= heights[i])
                right++;

            //比较最优解
            result = Math.max(result, (right - left + 1) * heights[i]);
        }

        return result;
    }


    //单调栈
    //思路:1. 记录一个单调递增栈,当出现一个小的值时,证明无法继续往右扩充,计算当前高度的面积    2. 使用 哨兵 ,优化代码
    public int largestRectangleArea2(int[] heights) {

        //构造一个新的数组,首尾添加一个为0的元素
        int[] height = new int[heights.length + 2];
        //偏移赋值
        for (int i = 0; i < heights.length; i++) {
            height[i+1] = heights[i];
        }

        Stack<Integer> s = new Stack<>();
        s.push(0);
        int result = 0;

        for (int i = 1; i < height.length; i++) {

            //这里也不需要判断栈空了,因为0永远 不会被弹出
            //如果出现比栈顶小的值
            while (height[s.peek()] > height[i]){

                /*
                不能调换顺序,比如[2,1,2]有问题,计算高度为1的时候,左边界仅仅到了1,但实际应该到第一个2
                int weight = i - s.peek();
                int high = height[s.pop()];
                 */

                int high = height[s.pop()];
                int weight = i - s.peek() - 1;

                //这里不需要考虑两个相邻栈顶值相同的原因:先出栈的那个可能没有计算到后出栈的情况,但是后出栈的一定是把先出栈的那一列考虑在内了
                result = Math.max(result, weight * high);
            }

            //又忘记入栈了
            s.push(i);
        }

        return result;
    }
}

你可能感兴趣的:(LeetCode,算法,数据结构,c++)